update
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
A short one-line action-based description, e.g. 'Tests if a function is valid'
|
||||
.DESCRIPTION
|
||||
A longer description of the function, its purpose, common use cases, etc.
|
||||
.NOTES
|
||||
Information or caveats about the function e.g. 'This function is not supported in Linux'
|
||||
.LINK
|
||||
Specify a URI to a help page, this will show when Get-Help -Online is used.
|
||||
.EXAMPLE
|
||||
Test-MyTestFunction -Verbose
|
||||
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
|
||||
#>
|
||||
|
||||
function New-ITDWindowsVM {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateSet('VMware', 'Azure')]
|
||||
[string]
|
||||
$Platform,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$ComputerName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]
|
||||
$CPU,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]
|
||||
$MemoryGB,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]
|
||||
$DiskOS,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]
|
||||
$DiskSwap,
|
||||
|
||||
[int]
|
||||
$DiskData = 0,
|
||||
|
||||
[Parameter(Mandatory = $true)] # this will decide Azure subscription
|
||||
[string]
|
||||
$Subnet,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$OS,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Environment,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$Datacenter,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$AppName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]
|
||||
$LicensingRestrictions,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
|
||||
}
|
||||
|
||||
process {
|
||||
switch ($Platform) {
|
||||
'VMware' {
|
||||
# New-ITDWindowsVmVmware
|
||||
}
|
||||
'Azure' {
|
||||
# New-ITDWindowsVmAzure
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
|
||||
}
|
||||
}
|
||||
+694
@@ -0,0 +1,694 @@
|
||||
<# ################
|
||||
.SYNOPSIS
|
||||
A short one-line action-based description, e.g. 'Tests if a function is valid'
|
||||
.DESCRIPTION
|
||||
A longer description of the function, its purpose, common use cases, etc.
|
||||
.NOTES
|
||||
Information or caveats about the function e.g. 'This function is not supported in Linux'
|
||||
.LINK
|
||||
Specify a URI to a help page, this will show when Get-Help -Online is used.
|
||||
.EXAMPLE
|
||||
$NewVMWindowsAzureParams = @{
|
||||
ComputerName = 'itdzmtest701.nd.gov';
|
||||
ResourceGroupNameOverride = 'rg-shared-iis-tst';
|
||||
AvailabilityZone = 2;
|
||||
CPU = 2;
|
||||
MemoryGB = 16;
|
||||
DiskOsGB = 128;
|
||||
DiskDataGB = 0;
|
||||
Subnet = '10.21.8.0/22';
|
||||
OS = 'Windows Server 2022 Datacenter';
|
||||
Environment = 'Test';
|
||||
AppName = 'ITD-POC-zmeier';
|
||||
LicensingRestrictions = "No Licensing Restrictions";
|
||||
}
|
||||
|
||||
New-ITDWindowsVmAzure @NewVMWindowsAzureParams -Credential $PrvCred -Verbose
|
||||
#>
|
||||
|
||||
function New-ITDWindowsVmAzure {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[string]
|
||||
$ComputerName,
|
||||
|
||||
[string]
|
||||
$ResourceGroupNameOverride,
|
||||
|
||||
[string]
|
||||
$AppName,
|
||||
|
||||
[ValidateSet(1, 2, 3)]
|
||||
[int]
|
||||
$AvailabilityZone,
|
||||
|
||||
[int]
|
||||
$CPU,
|
||||
|
||||
[int]
|
||||
$MemoryGB,
|
||||
|
||||
[int]
|
||||
$DiskOsGB,
|
||||
|
||||
[int]
|
||||
$DiskDataGB,
|
||||
|
||||
[string]
|
||||
$Subnet,
|
||||
|
||||
[string]
|
||||
$OS,
|
||||
|
||||
[string]
|
||||
$Environment,
|
||||
|
||||
#[string]
|
||||
#$Subscription,
|
||||
|
||||
[string]
|
||||
$LicensingRestrictions,
|
||||
|
||||
[PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
begin {
|
||||
|
||||
}
|
||||
|
||||
process {
|
||||
$ComputerName = $ComputerName.ToLower()
|
||||
$FQDN = $ComputerName
|
||||
$Hostname = $FQDN.split('.')[0]
|
||||
|
||||
Write-Verbose -Message "Prepare Connections"
|
||||
#$tenantId = '2dea0464-da51-4a88-bae2-b3db94bc0c54'
|
||||
#$AppId = '60244573-7130-4026-9c6d-47de73f8ca29'
|
||||
#$SecureStringPwd = '' #$Secret:AzureVMServicePrincipal #Pqt8Q~E-dDmQugcPPWdaK2t_4retS41VVVVOZbOx
|
||||
#$SecureStringPwd = 'Pqt8Q~E-dDmQugcPPWdaK2t_4retS41VVVVOZbOx'
|
||||
#$PSCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AppId, ($SecureStringPwd | ConvertTo-SecureString -AsPlainText -Force)
|
||||
#Connect-AzAccount -ServicePrincipal -Credential $PSCredential -Tenant $tenantId
|
||||
|
||||
Write-Verbose -Message "Prepare Credentials"
|
||||
$RadiusCred = New-Object System.Management.Automation.PSCredential($Credential.username.split('\')[1], ($Credential.Password))
|
||||
|
||||
Write-Verbose -Message "Infoblox: Find DNS pre-existing record, or create one"
|
||||
Clear-DnsClientCache
|
||||
$Cidr = $Subnet
|
||||
[Net.IpAddress]$NetworkId = $Cidr.split('/')[0]
|
||||
#######
|
||||
####### Remove 10.10.10.10 references when DNS sync is fixed
|
||||
#######
|
||||
[Net.IPAddress]$IpAddress = (Resolve-DnsName -Name $FQDN -Server 10.10.10.10 -ErrorAction SilentlyContinue).IPAddress
|
||||
$SubnetMaskInt = $CIDR.split('/')[1]
|
||||
$Int64 = ([convert]::ToInt64(('1' * $SubnetMaskInt + '0' * (32 - $SubnetMaskInt)), 2))
|
||||
[Net.IPAddress]$SubnetMask = '{0}.{1}.{2}.{3}' -f ([math]::Truncate($Int64 / 16777216)).ToString(),
|
||||
([math]::Truncate(($Int64 % 16777216) / 65536)).ToString(),
|
||||
([math]::Truncate(($Int64 % 65536) / 256)).ToString(),
|
||||
([math]::Truncate($Int64 % 256)).ToString()
|
||||
$IPSplit = $Subnet.Split('.')
|
||||
[Net.IPAddress]$DefaultGateway = ($IPSplit[0] + '.' + $IPSplit[1] + '.' + $IPSplit[2] + '.' + (($CIDR.split('/')[0].split('.')[-1] -as [int]) + 1) )
|
||||
|
||||
If ($null -ne $IpAddress) {
|
||||
If (($IpAddress.Address -band $SubnetMask.Address) -eq ($NetworkId.Address -band $SubnetMask.Address)) {
|
||||
Write-Warning "DNS record already exists, CIDR Block match"
|
||||
}
|
||||
Else {
|
||||
Write-Error "DNS record already exists, and does not match CIDR Block"
|
||||
Break
|
||||
}
|
||||
}
|
||||
Else {
|
||||
Write-Verbose -Message "Pre-existing IP address not found, creating new DNS record."
|
||||
New-ITDIbDNSRecordNextAvailableIP -Hostname $FQDN -CIDR $CIDR -Credential $RadiusCred
|
||||
Start-Sleep -Seconds 5
|
||||
Write-Verbose -Message ("FQDN is " + $FQDN)
|
||||
#######
|
||||
####### Remove 10.10.10.10 references when DNS sync is fixed
|
||||
#######
|
||||
#[Net.IPAddress]$IpAddress = (Resolve-DnsName -Name $FQDN -ErrorAction Stop -Server 10.10.10.10).IPAddress
|
||||
|
||||
[Net.IPAddress]$IpAddress = (Get-ITDIbDNSRecord -Hostname $FQDN -Credential $RadiusCred).IPv4Address
|
||||
|
||||
If ((Test-NetConnection -ComputerName $IpAddress.IPAddressToString).PingSucceeded) {
|
||||
Write-Error "IP Address already in use." -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose -Message "Passwordstate: If local administrator password does not exist in vault, create it."
|
||||
If ($FQDN -like "itdcnd*") {
|
||||
$PasswordStateList = "Peoplesoft Share PW"
|
||||
}
|
||||
Else {
|
||||
$PasswordStateList = "CSRC"
|
||||
}
|
||||
|
||||
$GuestVMLocalCredential = Get-ITDPassword -Title $FQDN -UserName itdadmin -Credential $Credential -ErrorAction SilentlyContinue
|
||||
If ($GuestVMLocalCredential) {
|
||||
Write-Verbose -Message "Passwordstate: Local admin password record already exists, use those credentials"
|
||||
}
|
||||
Else {
|
||||
Write-Verbose -Message "Passwordstate: Local admin password record does not exist, creating new credentials"
|
||||
$GuestVMLocalCredential = New-ITDPassword -Title $FQDN -UserName itdadmin -Description 'Local Administrator' -PasswordList $PasswordStateList -Credential $Credential
|
||||
}
|
||||
$GuestCredentialAB = New-Object System.Management.Automation.PSCredential ('itdadmin', ($GuestVMLocalCredential.GetNetworkCredential().Password | ConvertTo-SecureString -AsPlainText -Force))
|
||||
$GuestCredentialBB = New-Object System.Management.Automation.PSCredential ('Administrator', ($GuestVMLocalCredential.GetNetworkCredential().Password | ConvertTo-SecureString -AsPlainText -Force))
|
||||
|
||||
Write-Verbose -Message "Determine environment"
|
||||
switch ($Environment) {
|
||||
{ $_ -eq 'Test' -or $_ -eq 'Development' } {
|
||||
Write-Verbose -Message "Environment is Test or Development"
|
||||
$EnvShortString = 'tst'
|
||||
}
|
||||
'Production' {
|
||||
Write-Verbose -Message "Environment is Production"
|
||||
$EnvShortString = 'prd'
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose -Message "Determine subscription, via Subnet"
|
||||
$AllSubscriptions = Get-AzSubscription
|
||||
$AllAzVirtualNetworks = ForEach ($Subscription in $AllSubscriptions) {
|
||||
Set-AzContext -SubscriptionObject $Subscription | Out-Null
|
||||
Get-AzVirtualNetwork | ForEach-Object {
|
||||
[PSCustomObject]@{
|
||||
Subscription = $Subscription.Name;
|
||||
VirtualNetwork = $_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Subscription = ($AllAzVirtualNetworks | Where-Object { $_.VirtualNetwork.Subnets.AddressPrefix -match $Subnet }).Subscription
|
||||
$VirtualNetwork = ($AllAzVirtualNetworks | Where-Object { $_.VirtualNetwork.Subnets.AddressPrefix -match $Subnet }).VirtualNetwork
|
||||
$VirtualNetworkSubnet = $VirtualNetwork.Subnets | Where-Object { $_.AddressPrefix -match $Subnet }
|
||||
|
||||
$VNetName = $VirtualNetwork.Name
|
||||
$VNetSubnet = $VirtualNetworkSubnet.Name
|
||||
|
||||
switch ($OS) {
|
||||
"Windows Server 2019 Datacenter" {
|
||||
$VMOS = "Windows"
|
||||
$Publisher = "MicrosoftWindowsServer"
|
||||
$Offer = "WindowsServer"
|
||||
$sku = "2019-Datacenter"
|
||||
}
|
||||
"Windows Server 2022 Datacenter" {
|
||||
$VMOS = "Windows"
|
||||
$Publisher = "MicrosoftWindowsServer"
|
||||
$Offer = "WindowsServer"
|
||||
$sku = "2022-datacenter"
|
||||
}
|
||||
Default { Write-Error "Invalid operating system" -ErrorAction Stop }
|
||||
}
|
||||
|
||||
# finalize VM location and size
|
||||
$location = "centralus"
|
||||
$VMSizeFilter1 = @(
|
||||
"Standard_D2ds_v5",
|
||||
"Standard_D4ds_v5",
|
||||
"Standard_D8ds_v5",
|
||||
"Standard_D16ds_v5",
|
||||
"Standard_D32ds_v5",
|
||||
"Standard_E2ds_v5",
|
||||
"Standard_E4ds_v5",
|
||||
"Standard_E8ds_v5",
|
||||
"Standard_E16ds_v5",
|
||||
"Standard_E20ds_v5",
|
||||
"Standard_E32ds_v5",
|
||||
"Standard_F2s_v2",
|
||||
"Standard_F4s_v2",
|
||||
"Standard_F8s_v2",
|
||||
"Standard_F16s_v2",
|
||||
"Standard_F32s_v2"
|
||||
)
|
||||
|
||||
$VMSize = Get-AzVMSize -Location centralus | `
|
||||
Where-Object { $VMSizeFilter1 -contains $_.Name } | `
|
||||
Where-Object { $_.NumberOfCores -ge $CPU -and $_.MemoryInMB -ge ($Memory * 1024) } | `
|
||||
Where-Object Name -NotMatch "_Promo" | `
|
||||
Sort-Object NumberOfCores, MemoryInMB | `
|
||||
Select-Object -First 1
|
||||
|
||||
Write-Verbose -Message "Determine ResourceGroupName, and create Resource Group if needed"
|
||||
If ($PSBoundParameters.ContainsKey('ResourceGroupNameOverride')) {
|
||||
# use the name in the variable
|
||||
Write-Verbose -Message "ResourceGroupName parameter found, is $ResourceGroupNameOverride"
|
||||
$ResourceGroupName = $ResourceGroupNameOverride
|
||||
}
|
||||
Else {
|
||||
Write-Verbose -Message "ResourceGroupName parameter not found, determine now"
|
||||
# if name is not given, determine the name
|
||||
$VMOwner = $AppName.split('-')[0].ToLower()
|
||||
$VMFunction = (($AppName -replace "$VMOwner-") -replace "-").ToLower() -replace " "
|
||||
$ResourceGroupName = "rg-$VMOwner-$VMFunction-$EnvShortString"
|
||||
}
|
||||
Write-Verbose -Message "ResourceGroupName is $ResourceGroupName"
|
||||
|
||||
Write-Verbose -Message "Change to selected subscription and validate resource group exists"
|
||||
Set-AzContext $Subscription | Out-Null
|
||||
$ResGroupExist = $null
|
||||
$ResGroupExist = Get-AzResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue
|
||||
|
||||
If (@($ResGroupExist).count -gt 1) {
|
||||
Write-Error "Multiple Resource Groups matched" -ErrorAction Stop
|
||||
}
|
||||
If (@($ResGroupExist).count -lt 1) {
|
||||
Write-Warning "No matching resource group found, creating it now"
|
||||
New-AzResourceGroup -Name $ResourceGroupName -Location $Location -Tag @{ApplicationName = $AppName }
|
||||
}
|
||||
If (@($ResGroupExist).count -eq 1) {
|
||||
Write-Verbose -Message "Exactly one matching resource group found"
|
||||
}
|
||||
|
||||
$VMName = "vm-$HostName-$EnvShortString"
|
||||
$VMIPConfigName = "ipconfig-$HostName-$EnvShortString"
|
||||
$VMNicName = "nic-$HostName-$EnvShortString"
|
||||
$VMObjectName = "vm-$HostName-$EnvShortString"
|
||||
$VMOsDiskName = "vm-$HostName-os-$EnvShortString"
|
||||
|
||||
Write-Verbose -Message "Verifying Applicable Inputs are Lowercase"
|
||||
$VMIPConfigName = $VMIPConfigName.ToLower()
|
||||
$VMNicName = $VMNicName.ToLower()
|
||||
$VMObjectName = $VMObjectName.ToLower()
|
||||
$VMOsDiskName = $VMOSDiskName.ToLower()
|
||||
|
||||
Write-Verbose -Message "Creating IPConfig and NIC"
|
||||
$IPConfig = New-AzNetworkInterfaceIpConfig -Name $VMIPConfigName -PrivateIpAddress $IPAddress.IPAddressToString -PrivateIpAddressVersion IPv4 -Subnet $VirtualNetworkSubnet
|
||||
$VMNIC = New-AzNetworkInterface -IpConfigurationName $IPConfig -Location $Location -Name $VMNICName -ResourceGroupName $ResourceGroupName -Subnet $VirtualNetworkSubnet -Force
|
||||
$VMNIC.IpConfigurations[0].PrivateIpAllocationMethod = "Static"
|
||||
$VMNIC.IpConfigurations[0].PrivateIpAddress = $IPAddress.IPAddressToString
|
||||
Set-AzNetworkInterface -NetworkInterface $VMNIC
|
||||
|
||||
Write-Verbose -Message "Build VM Config"
|
||||
$vmConfigParams = @{
|
||||
VMName = $VMObjectName
|
||||
VMSize = $VMSize.Name
|
||||
}
|
||||
|
||||
If ($PSBoundParameters.ContainsKey('AvailabilityZone')) {
|
||||
Write-Verbose -Message "AvailabilityZone parameter found, adding to vmConfigParams"
|
||||
$vmConfigParams += @{
|
||||
Zone = $AvailabilityZone
|
||||
}
|
||||
}
|
||||
|
||||
$vmConfig = New-AzVMConfig @vmConfigParams
|
||||
$vmConfig | Set-AzVMOSDisk -Name $VMOSDiskName -CreateOption FromImage
|
||||
If ($VMOS -eq "Windows") {
|
||||
$vmConfig | Set-AzVMOperatingSystem -Windows -ComputerName $VMName -Credential $GuestVMLocalCredential
|
||||
$vmConfig | Set-AzVMSourceImage -PublisherName $Publisher -Offer $Offer -Skus $Sku -Version latest
|
||||
$vmConfig.OSProfile.ComputerName = $HostName
|
||||
}
|
||||
If ($VMOS -eq "Linux") {
|
||||
$vmConfig | Set-AzVMOperatingSystem -Linux -ComputerName $VMFQDN -Credential $GuestVMLocalCredential
|
||||
Switch ($VMSubscription) {
|
||||
"npd01" { $vmConfig | Set-AzVMSourceImage -Id "/subscriptions/76297098-764c-43de-8525-c9fda1b237be/resourceGroups/rg-infra-templates-tst-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-103" }
|
||||
"infra01" { $vmConfig | Set-AzVMSourceImage -Id "/subscriptions/e53aa0c7-824d-40a2-b420-4ab77b1051d2/resourceGroups/rg-infra-templates-prd-001/providers/Microsoft.Compute/images/vm-rhel74template-prd-403" }
|
||||
"prd01" { $vmConfig | Set-AzVMSourceImage -Id "/subscriptions/437b2bfa-850e-4464-b6c2-38a68cda7c69/resourceGroups/rg-infra-templates-prd-002/providers/Microsoft.Compute/images/vm-rhel74template-prd-003" }
|
||||
}
|
||||
}
|
||||
|
||||
$vmConfig | Add-AzVMNetworkInterface -Id $VMNIC.ID
|
||||
Set-AzVMBootDiagnostic -VM $vmConfig -Enable -ResourceGroupName $ResourceGroupName
|
||||
|
||||
Write-Verbose "Creating VM"
|
||||
New-AzVM -VM $vmConfig -ResourceGroupName $ResourceGroupName -Location $Location -DisableBginfoExtension -LicenseType "Windows_Server" #-AsJob
|
||||
|
||||
Start-Sleep -Seconds 60
|
||||
|
||||
$VM = Get-AzVM -Name $VMObjectName -ResourceGroupName $ResourceGroupName
|
||||
|
||||
If ($PSBoundParameters.ContainsKey("DiskDataGB")) {
|
||||
$ExistingDisks = @($VM.StorageProfile.DataDisks | Select-Object *, @{n = 'ItdId'; e = { [int]($_.Name -replace "vm-$hostname-app-$environment-") } })
|
||||
|
||||
$NewDiskItdIdInt = ($ExistingDisks | Sort-Object ItdId -Descending | Select-Object -First 1).ItdId + 1
|
||||
$NewDiskItdIdStr = $NewDiskItdIdInt.ToString("000")
|
||||
$NewDiskName = "vm-$Hostname-app-$EnvShortString-$NewDiskItdIdStr" #vm-itduc4p1-app-tst-001
|
||||
|
||||
$LunID = ($ExistingDisks | Sort-Object Lun -Descending | Select-Object -First 1).Lun + 1
|
||||
|
||||
$count = 0
|
||||
|
||||
If ($ExistingDisks) {
|
||||
while ($Size -match $ExistingDisks.DiskSizeGB) {
|
||||
$count++
|
||||
Write-Verbose -Message "SizeGB: $Size, Count: $count"
|
||||
If ($count -ge 11) {
|
||||
Write-Error "Disk size not available" -ErrorAction Stop
|
||||
}
|
||||
Else {
|
||||
$Size = $Size - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose -Message "SizeGB: $Size, Count: $count"
|
||||
|
||||
$AzureRmDiskConfigParams = @{
|
||||
DiskSizeGB = $DiskDataGB
|
||||
Location = $Location
|
||||
CreateOption = "Empty"
|
||||
SkuName = "Premium_LRS"
|
||||
}
|
||||
|
||||
If ($Zone) {
|
||||
Write-Verbose "VM is located in Zone $Zone"
|
||||
$AzureRmDiskConfigParams += @{Zone = $Zone }
|
||||
}
|
||||
#$DiskConfig = New-AzureRmDiskConfig -DiskSizeGB $Size -Location $Location -CreateOption Empty -SkuName Premium_LRS
|
||||
$DiskConfig = New-AzDiskConfig @AzureRmDiskConfigParams
|
||||
|
||||
If (!(Get-AzDisk -ResourceGroupName $ResourceGroupName -DiskName $NewDiskName -ErrorAction SilentlyContinue)) {
|
||||
$NewDisk = New-AzDisk -DiskName $NewDiskName -Disk $DiskConfig -ResourceGroupName $ResourceGroupName
|
||||
|
||||
$VM = Add-AzVMDataDisk -Name $NewDiskName -CreateOption Attach -ManagedDiskId $NewDisk.Id -VM $VM -Lun $LunID -Caching ReadOnly
|
||||
Update-AzVM -VM $VM -ResourceGroupName $ResourceGroupName -AsJob
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose -Message "Wait two minutes before Pre-Firewall Guest OS customization"
|
||||
Start-Sleep -Seconds 120
|
||||
|
||||
Write-Verbose -Message "Begin Pre-Firewall Guest OS customization"
|
||||
$InvokeAzVMRunCommandParams = @{
|
||||
ResourceGroupName = $ResourceGroupName;
|
||||
Name = $VMName;
|
||||
CommandId = 'RunPowerShellScript'
|
||||
}
|
||||
|
||||
Write-Verbose -Message "1-Set WMI Tags"
|
||||
$ScriptBlock = {
|
||||
try {
|
||||
Write-Verbose "Create new Class"
|
||||
$Class = New-Object System.Management.ManagementClass("root\cimv2", [String]::Empty, $null);
|
||||
|
||||
$Class["__CLASS"] = "ITD";
|
||||
$Class.Qualifiers.Add("Static", $true)
|
||||
$Class.Properties.Add("MyKey", [System.Management.CimType]::String, $false)
|
||||
$Class.Properties["MyKey"].Qualifiers.Add("Key", $true)
|
||||
|
||||
$Class.Properties.Add("LastModified", [System.Management.CimType]::String, $false)
|
||||
$Class.Properties.Add("DTAP", [System.Management.CimType]::String, $false)
|
||||
$Class.Properties.Add("Baseline", [System.Management.CimType]::String, $false)
|
||||
|
||||
$Class.Put()
|
||||
|
||||
Write-Verbose "Create single ITD Object"
|
||||
Set-WmiInstance -Class ITD -Arguments @{LastModified = (Get-Date); DTAP = "Prod"; Baseline = "000" }
|
||||
}
|
||||
catch {
|
||||
Throw $_
|
||||
Break
|
||||
}
|
||||
}
|
||||
Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString $ScriptBlock
|
||||
|
||||
Write-Verbose -Message "3-Disk Configuration"
|
||||
$ScriptBlock = {
|
||||
try {
|
||||
# Non-initialized and MBR-initialized disks will have 0 partitions by default, but GPT-initialized disks will have 1 system reserved partition by default
|
||||
$disks = Get-Disk | Where-Object { $_.NumberOfPartitions -eq 0 -or ( $_.PartitionStyle -eq 'GPT' -and $_.NumberOfPartitions -eq 1 ) } | Sort-Object -Property Number
|
||||
|
||||
if ($disks) {
|
||||
Write-Verbose -Message "Found $(@($disks).Count) unpartitioned disks."
|
||||
|
||||
# Prevent the "You must format this partition before using it." popup
|
||||
if (Get-Service ShellHWDetection -ErrorAction SilentlyContinue) { Stop-Service ShellHWDetection -ErrorAction SilentlyContinue }
|
||||
|
||||
foreach ($disk in $disks) {
|
||||
if ($disk.IsOffline) {
|
||||
Set-Disk $disk.Number -IsOffline $false
|
||||
Write-Verbose -Message "Brought disk $($disk.Number)($("{0:n0}GB" -f ($disk.Size / 1GB))) online..."
|
||||
}
|
||||
|
||||
if ($disk.IsReadOnly) { Set-Disk $disk.Number -IsReadOnly $false }
|
||||
if ($disk.PartitionStyle -eq 'RAW') { Initialize-Disk $disk.Number -PartitionStyle GPT -ErrorAction SilentlyContinue }
|
||||
|
||||
$diskParam = @{
|
||||
FileSystem = 'NTFS'
|
||||
Confirm = $false
|
||||
}
|
||||
|
||||
$driveLetter = [Int][Char]'D'
|
||||
while (Get-Volume -DriveLetter $([Char]$driveLetter) -ErrorAction SilentlyContinue) {
|
||||
$driveLetter++
|
||||
}
|
||||
|
||||
$diskParam.DriveLetter = [Char]$driveLetter
|
||||
|
||||
if (@($disks).IndexOf($disk) -eq 0 -and (-not (Get-Volume -DriveLetter D -ErrorAction SilentlyContinue))) {
|
||||
$diskParam.NewFileSystemLabel = 'Temporary Storage'
|
||||
}
|
||||
elseif (@($disks).IndexOf($disk) -eq 1 -and (-not (Get-Volume -DriveLetter E -ErrorAction SilentlyContinue))) {
|
||||
$diskParam.NewFileSystemLabel = 'Data'
|
||||
}
|
||||
|
||||
[void](New-Partition -DiskNumber $disk.Number -DriveLetter $diskParam.DriveLetter -UseMaximumSize)
|
||||
[void](Format-Volume @diskParam)
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Verbose -Message "No unpartitioned disks found, continuing..."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Throw $_
|
||||
Break
|
||||
}
|
||||
finally {
|
||||
if (Get-Service ShellHWDetection -ErrorAction SilentlyContinue) { Start-Service ShellHWDetection -ErrorAction SilentlyContinue }
|
||||
}
|
||||
}
|
||||
Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString $ScriptBlock
|
||||
|
||||
Write-Verbose -Message "5-Time Zone"
|
||||
$ScriptBlock = {
|
||||
if ((Get-TimeZone).Id -ne 'Central Standard Time') {
|
||||
Write-Verbose -Message "Current time zone set to $((Get-TimeZone).Id), setting to Central Standard Time."
|
||||
|
||||
Set-TimeZone -Id 'Central Standard Time'
|
||||
|
||||
Write-Verbose -Message "Time zone set to Central Standard Time."
|
||||
}
|
||||
else {
|
||||
Write-Verbose -Message "Time zone is already set to Central Standard Time."
|
||||
}
|
||||
}
|
||||
Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString $ScriptBlock
|
||||
|
||||
Write-Verbose -Message "6-Enable Performance Counters"
|
||||
$ScriptBlock = {
|
||||
# Enable Performance Counters
|
||||
try {
|
||||
if (Get-ScheduledTask -TaskName "Server Manager Performance Monitor" | Where-Object State -NE "Running" -ErrorAction SilentlyContinue) {
|
||||
Enable-ScheduledTask -TaskPath "\Microsoft\Windows\PLA\" -TaskName "Server Manager Performance Monitor" | Start-ScheduledTask
|
||||
|
||||
Write-Verbose -Message "Performance monitors enabled."
|
||||
}
|
||||
else {
|
||||
Write-Verbose -Message "Performance monitors already enabled, continuing..."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Throw $_
|
||||
Break
|
||||
}
|
||||
}
|
||||
Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString $ScriptBlock
|
||||
|
||||
Write-Verbose -Message "7-Disable Windows Firewall"
|
||||
$ScriptBlock = {
|
||||
# Disable Windows Firewall
|
||||
Write-Verbose -Message "Checking for active Windows Firewall..."
|
||||
|
||||
if ((Get-NetFirewallProfile).Enabled -contains 'True') {
|
||||
Write-Verbose -Message "Windows Firewall is still enabled, disabling it..."
|
||||
|
||||
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False
|
||||
|
||||
Write-Verbose -Message "Windows Firewall disabled."
|
||||
}
|
||||
else {
|
||||
Write-Verbose -Message "Windows Firewall already disabled, continuing..."
|
||||
}
|
||||
}
|
||||
Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString $ScriptBlock
|
||||
|
||||
# determine Active Directory Forest and OU
|
||||
Write-Verbose -Message "8a-Determine domain join"
|
||||
$DomainName = $FQDN.Substring($FQDN.IndexOf(".") + 1)
|
||||
switch ($DomainName) {
|
||||
'nd.gov' {
|
||||
$SearchBaseDomain = "dc=nd,dc=gov"
|
||||
}
|
||||
'ndcloud.gov' {
|
||||
$SearchBaseDomain = "dc=ndcloud,dc=gov"
|
||||
}
|
||||
}
|
||||
|
||||
If ($DomainName -eq "nd.gov") {
|
||||
$OUAppName = Get-ADOrganizationalUnit -Server $DomainName -SearchBase ("OU=Windows,OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq $AppName }
|
||||
If (!($OUAppName)) {
|
||||
$OUAppName = Get-ADOrganizationalUnit -SearchBase ("OU=Windows,OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq 'All-General' }
|
||||
}
|
||||
$ExistingADComputer = Get-ADComputer -Filter { Name -eq $Hostname }
|
||||
If ($ExistingADComputer) {
|
||||
If ($ExistingADComputer.DistinguishedName -like ("*" + $AppName + "*") -or $ExistingADComputer.DistinguishedName -like "*All-General*") {
|
||||
Write-Warning "AD object already exists, OU path does match"
|
||||
$OuFinal = $ExistingADComputer.DistinguishedName -replace '^.+?(?<!\\),', ''
|
||||
}
|
||||
Else {
|
||||
Write-Error "AD object already exists, OU path mismatch"
|
||||
Exit
|
||||
Exit
|
||||
}
|
||||
}
|
||||
Else {
|
||||
switch ($Environment) {
|
||||
'Test' {
|
||||
If ($AppName -like "Shared-Peoplesoft*") { $EnvString = "Non-Prod" }
|
||||
Else { $EnvString = "Test" }
|
||||
$OuAppNameEnv = Get-ADOrganizationalUnit -SearchBase $OUAppName.DistinguishedName -Filter * | Where-Object Name -EQ "$EnvString"
|
||||
}
|
||||
'Production' {
|
||||
If ($AppName -like "Shared-Peoplesoft*") { $EnvString = "Prod" }
|
||||
Else { $EnvString = "Prod" }
|
||||
|
||||
$OuAppNameEnv = Get-ADOrganizationalUnit -SearchBase $OUAppName.DistinguishedName -Filter * | Where-Object Name -EQ "$EnvString"
|
||||
}
|
||||
}
|
||||
If ($OuAppNameEnv) { $OUFinal = $OUAppNameEnv.DistinguishedName }
|
||||
Else { $OuFinal = $OUAppName.DistinguishedName }
|
||||
}
|
||||
}
|
||||
|
||||
# wait for firewall and reconnect
|
||||
Write-Verbose -Message "8b-Verify if firewall is open before domain join attempt"
|
||||
$connectivity = $false
|
||||
while ($connectivity -eq $false) {
|
||||
If (Test-NetConnection -ComputerName $IpAddress) {
|
||||
Write-Verbose -Message "Ping successful" -Verbose
|
||||
$connectivity = $true
|
||||
}
|
||||
Else {
|
||||
Write-Verbose -Message "Ping failed, may need to wait for PA IP sync" -Verbose
|
||||
Start-Sleep -Seconds 60
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose -Message "8c-Attempt domain join"
|
||||
switch ($DomainName) {
|
||||
'nd.gov' {
|
||||
Write-Verbose -Message "Attempting domain join nd.gov"
|
||||
Write-Verbose -Message "Domain: $DomainName"
|
||||
Write-Verbose -Message "OuPath: $OuFinal"
|
||||
<#Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptPath 'C:\AzWinBuild\8-Domain-ndgov.ps1' -Parameter @{
|
||||
"DomainName" = 'nd.gov';
|
||||
"OuPath" = "$OuFinal"
|
||||
}#>
|
||||
$ScriptBlock = {
|
||||
Param(
|
||||
[string]
|
||||
$DomainName,
|
||||
|
||||
[string]
|
||||
$OuPath
|
||||
)
|
||||
|
||||
Write-Host $OuPath
|
||||
Test-NetConnection -ComputerName nd.gov
|
||||
|
||||
$DomainJoinCred = New-Object System.Management.Automation.PSCredential('ndgov\svcitdvmdomainjoin', ('hypes-Vgv8h89' | ConvertTo-SecureString -AsPlainText -Force))
|
||||
Add-Computer -DomainName $DomainName -OUPath $OuPath -Credential $DomainJoinCred
|
||||
|
||||
Restart-Computer -Force
|
||||
}
|
||||
Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString $ScriptBlock -Parameter @{
|
||||
"DomainName" = 'nd.gov';
|
||||
"OuPath" = "$OuFinal"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Start-Sleep -Seconds 120
|
||||
|
||||
Write-Verbose -Message "10a-Copy SCCM client from itdsccmp2.nd.gov" -Verbose
|
||||
$ScriptBlock = { #### NEEDS WORK
|
||||
Param(
|
||||
|
||||
)
|
||||
|
||||
Copy-Item -path "\\itdsccmp2.nd.gov\SCCM_Client\Client\" -Destination C:\temp\SCCM_Client -Recurse
|
||||
}
|
||||
|
||||
$CopySuccess = $false
|
||||
$CopyAttempts = 0
|
||||
While ($CopySuccess -eq $false -and $CopyAttempts -lt 100) {
|
||||
$Attempts++
|
||||
$InvokeResult = Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString $ScriptBlock
|
||||
If ($InvokeResult.value.message -like "Copy-Item : Cannot find path*") {
|
||||
Write-Verbose -Message "SCCM Client file copy failed. Looping until it works." -Verbose
|
||||
$CopySuccess = $false
|
||||
}
|
||||
Else {
|
||||
Write-Verbose -Message "SCCM Client file copy success." -Verbose
|
||||
$CopySuccess = $true
|
||||
}
|
||||
}
|
||||
|
||||
# Check if SCCM automatically installed the SCCM client and registered it
|
||||
$CcmRegistered = $false
|
||||
$CcmRegistration = Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString {
|
||||
Get-Content C:\Windows\CCM\Logs\ClientIDManagerStartup.log | Select-String RegTask
|
||||
}
|
||||
If ($CcmRegistration.value.message -match "Client is registered") {
|
||||
Write-Verbose "Client is registered."
|
||||
$CcmRegistered = $true
|
||||
}
|
||||
ElseIf ($CcmRegistration.value.message -match "Client is already registered") {
|
||||
Write-Verbose "Client is already registered."
|
||||
$CcmRegistered = $true
|
||||
}
|
||||
If ($CcmRegistered -eq $false) {
|
||||
Invoke-AzVMRunCommand @InvokeAzVMRunCommandParams -ScriptString {
|
||||
|
||||
If (Get-Process -Name ccmsetup -ErrorAction SilentlyContinue) {
|
||||
Write-Warning "CCM client is already installing"
|
||||
$CcmRegistered = $true
|
||||
}
|
||||
ElseIf (Get-Process -Name ccmexec -ErrorAction SilentlyContinue) {
|
||||
Write-Warning "CCM client is already installed"
|
||||
$CcmRegistered = $true
|
||||
}
|
||||
Else {
|
||||
Write-Warning -Message "Installing SCCM Client..."
|
||||
Invoke-Expression -Command "C:\temp\SCCM_Client\ccmsetup.exe SMSSITECODE=ITD SMSMP=itdsccmp2.nd.gov DNSSUFFIX=nd.gov"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose -Message "[$FQDN]:Approve SCCM Client"
|
||||
#Start-Sleep -Seconds 30 # ADD LOOP/SMARTS TO WAIT FOR DISCOVERY AND ANOTHER FOR APPROVAL
|
||||
Invoke-Command -ComputerName itdsccmp2.nd.gov -Credential $Credential -ArgumentList $Hostname -ScriptBlock {
|
||||
Import-Module 'D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
|
||||
$PSDrives = Get-PSDrive
|
||||
If ($PSDrives | Where-Object Name -EQ "ITD") {
|
||||
# ITD Drive exists, do nothing
|
||||
}
|
||||
else {
|
||||
New-PSDrive -Name "ITD" -PSProvider AdminUI.PS.Provider\CMSite -Root itdsccmp2.nd.gov
|
||||
}
|
||||
|
||||
Set-Location ITD:\
|
||||
$Device = Get-CMDevice -Name $args[0]
|
||||
If ($Device.IsApproved -eq 0) {
|
||||
Approve-CMDevice -DeviceName $args[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
|
||||
}
|
||||
}
|
||||
+1037
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user