This commit is contained in:
Zack Meier
2026-04-15 15:45:50 -05:00
commit 1d304511b8
613 changed files with 140998 additions and 0 deletions
@@ -0,0 +1,176 @@
[CmdletBinding()] #
param (
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTask')]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$FQDN,
[Parameter(ParameterSetName = 'FromSCTask')]
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry', HelpMessage = "Example: Standard_D4ds_v5")]
[string]
$VMSizeOverride,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$DiskOsGB = 128,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$DiskDataGB = 20,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$Subnet,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$OS = 'Windows Server 2022',
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$VMEnvironment,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$AppName,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$LicensingRestrictions = 'No Licensing Restrictions',
[string]
$ResourceGroupNameOverride,
[ValidateSet('1', '2', '3')]
[int]
$AvailabilityZone
)
switch ($PSCmdlet.ParameterSetName) {
'ManualEntry' {
$NewITDWindowsVmAzureParams = @{
FQDN = $FQDN;
AppName = $AppName;
VMSizeOverride = $VMSizeOverride;
#CPU = $CPU;
#MemoryGB = $MemoryGB;
DiskOsGB = $DiskOsGB;
DiskDataGB = $DiskDataGB;
Subnet = $Subnet;
OS = $OS;
VMEnvironment = $VMEnvironment;
LicensingRestrictions = $LicensingRestrictions;
}
switch ($PSBoundParameters.Keys) {
'ResourceGroupNameOverride' { $NewITDWindowsVmAzureParams += @{ ResourceGroupNameOverride = $ResourceGroupNameOverride } }
'AvailabilityZone' { $NewITDWindowsVmAzureParams += @{ AvailabilityZone = $AvailabilityZone } }
}
}
'FromSCTask' {
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" { $ServiceNowEnvironment = 'Test' }
"ITDWINAUTOP1" { $ServiceNowEnvironment = 'Production' }
}
Write-Verbose -Message "New-ITDServiceNowSession" -Verbose
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -SysId ($SCTask.request_item.value) -IncludeVariableSet -IncludeCustomVariable
$FqdnFromSCTaskDescription = ($SCTask.short_description).display_value.split(' ')[7]
$NewITDWindowsVmAzureParams = @{
FQDN = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).host_name );
DiskOsGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).disk_1_os );
DiskDataGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).disk_3 );
Subnet = ( Get-ITDServiceNowRecord -Table 'cmdb_ci_ip_network' -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq "$FqdnFromSCTaskDescription" }).cidr_block).name.display_value;
OS = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).target_os_version_windows );
VMEnvironment = ( $Ritm.customvariable.environment.value );
AppName = ( Get-ITDServiceNowRecord -Table 'cmdb_ci_service' -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq "$FqdnFromSCTaskDescription" }).application_info).name.display_value;
LicensingRestrictions = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).licensing_restrictions );
}
switch ($PSBoundParameters.Keys) {
'ResourceGroupNameOverride' {
Write-Warning -Message "ResourceGroupNameOverride found $ResourceGroupNameOverride"
$NewITDWindowsVMAzureParams += @{ ResourceGroupNameOverride = $ResourceGroupNameOverride }
}
'AvailabilityZone' {
Write-Warning -Message "ResourceGroupNameOverride found $AvailabilityZone"
$NewITDWindowsVMAzureParams += @{ AvailabilityZone = $AvailabilityZone }
}
'VMSizeOverride' {
Write-Warning -Message "VMSizeOverride found $VMSizeOverride"
$NewITDWindowsVMAzureParams += @{ VMSizeOverride = $VMSizeOverride }
}
}
If ($NewITDWindowsVmAzureParams.VMSizeOverride) {
# do nothing
} Else {
$NewITDWindowsVMAzureParams += @{ CPU = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).processors );}
$NewITDWindowsVMAzureParams += @{ MemoryGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).memory_gb );}
}
}
}
Write-Verbose -Message "Connect to Azure using Service Principal" -Verbose
$tenantId = '2dea0464-da51-4a88-bae2-b3db94bc0c54'
$AppId = '60244573-7130-4026-9c6d-47de73f8ca29'
$SecureStringPwd = $Secret:azure_iaasserviceprincipal
$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 "Attempt server provisioning" -Verbose
Write-Verbose -Message "NewITDWindowsVMAzureParams:" -Verbose
Write-Verbose -Message ("FQDN " + $NewITDWindowsVMAzureParams.FQDN) -Verbose
Write-Verbose -Message ("VMSizeOverride " + $NewITDWindowsVMAzureParams.VMSizeOverride) -Verbose
Write-Verbose -Message ("DiskOsGB " + $NewITDWindowsVMAzureParams.DiskOsGB) -Verbose
Write-Verbose -Message ("DiskDataGB " + $NewITDWindowsVMAzureParams.DiskDataGB) -Verbose
Write-Verbose -Message ("Subnet " + $NewITDWindowsVMAzureParams.Subnet) -Verbose
Write-Verbose -Message ("OS " + $NewITDWindowsVMAzureParams.OS) -Verbose
Write-Verbose -Message ("VMEnvironment " + $NewITDWindowsVMAzureParams.Environment) -Verbose
Write-Verbose -Message ("AppName " + $NewITDWindowsVMAzureParams.AppName) -Verbose
Write-Verbose -Message ("LicensingRestrictions " + $NewITDWindowsVMAzureParams.LicensingRestrictions) -Verbose
try {
New-ITDWindowsVmAzureStep1 @NewITDWindowsVmAzureParams -Credential $Secret:ndgov_svcitdiaasauto -Verbose
Write-Verbose -Message "New-ITDWindowsVmAzureStep1 function completed"
$Step1Complete = $true
}
catch {
$Step1Complete = $false
switch ($PSCmdlet.ParameterSetName) {
'FromSCTask' {
$ErrorText = ($_.ErrorDetails.message | ConvertFrom-Json).text
If ($ErrorText -match "Cannot find 1 available IP address" ) {
$Msg = "Resolve the issue and resubmit the Server Build Request catalog item. Setting $SCTaskNum State to Closed Incomplete"
Write-Warning -Message $Msg
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("Azure build step 1 errored. $Msg. `nPSU Job Id #" + $UAJob.Id + " `n" + $ErrorText)
state = 'Closed Incomplete'
}
}
}
}
throw
}
switch ($PSCmdlet.ParameterSetName) {
'FromSCTask' {
Write-Verbose -Message ("Update " + $SCTaskNum + " with Step 1 status") -Verbose
switch ($Step1Complete) {
$true {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("Azure build step 1 complete. `nPSU Job Id #" + $UAJob.Id)
}
}
$false {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("Azure build step 1 errored, needs human review. `nPSU Job Id #" + $UAJob.Id)
}
}
}
}
}
@@ -0,0 +1,151 @@
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTask')]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$ComputerName,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
<<<<<<< HEAD
[string]
$VMSizeOverride,
<<<<<<< HEAD
<#
=======
<#
>>>>>>> main
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
=======
>>>>>>> 828a9d5a994531efc47fe9ca78c93cfb076c6ba4
[int]
$CPU = 1,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$MemoryGB = 4,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$DiskOsGB = 128,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$DiskDataGB = 20,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$Subnet,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$OS = 'Windows Server 2022 Datacenter',
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$Environment,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$AppName,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$LicensingRestrictions = 'No Licensing Restrictions',
[string]
$ResourceGroupNameOverride,
[ValidateSet('1', '2', '3')]
[int]
$AvailabilityZone
)
switch ($PSCmdlet.ParameterSetName) {
'ManualEntry' {
$NewITDWindowsVmAzureParams = @{
ComputerName = $ComputerName;
AppName = $AppName;
<<<<<<< HEAD
<<<<<<< HEAD
VMSizeOverride = $VMSizeOverride;
=======
VMSizeOverride = $VMSizeOverride;
>>>>>>> main
#CPU = $CPU;
#MemoryGB = $MemoryGB;
=======
CPU = $CPU;
MemoryGB = $MemoryGB;
>>>>>>> 828a9d5a994531efc47fe9ca78c93cfb076c6ba4
DiskOsGB = $DiskOsGB;
DiskDataGB = $DiskDataGB;
Subnet = $Subnet;
OS = $OS;
Environment = $Environment;
LicensingRestrictions = $LicensingRestrictions;
}
switch ($PSBoundParameters.Keys) {
'ResourceGroupNameOverride' { $NewITDWindowsVmAzureParams += @{ ResourceGroupNameOverride = $ResourceGroupNameOverride } }
'AvailabilityZone' { $NewITDWindowsVmAzureParams += @{ AvailabilityZone = $AvailabilityZone } }
}
}
'FromSCTask' {
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" { $ServiceNowEnvironment = 'Test' }
"ITDWINAUTOP1" { $ServiceNowEnvironment = 'Production' }
}
Write-Verbose -Message "New-ITDServiceNowSession" -Verbose
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -SysId ($SCTask.request_item.value) -IncludeVariableSet -IncludeCustomVariable
$FqdnFromSCTaskDescription = ($SCTask.short_description).display_value.split(' ')[7]
$NewITDWindowsVmAzureParams = @{
ComputerName = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).host_name );
CPU = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).processors );
MemoryGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).memory_gb );
DiskOsGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).disk_1_os );
DiskDataGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).disk_3 );
Subnet = ( Get-ITDServiceNowRecord -Table 'cmdb_ci_ip_network' -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq "$FqdnFromSCTaskDescription" }).cidr_block).name.display_value;
OS = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).target_os_version_windows );
Environment = ( $Ritm.customvariable.environment.value );
AppName = ( Get-ITDServiceNowRecord -Table 'cmdb_ci_service' -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq "$FqdnFromSCTaskDescription" }).application_info).name.display_value;
LicensingRestrictions = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).licensing_restrictions );
}
switch ($PSBoundParameters.Keys) {
'ResourceGroupNameOverride' {
Write-Warning -Message "ResourceGroupNameOverride found $ResourceGroupNameOverride"
$NewITDWindowsVMAzureParams += @{ ResourceGroupNameOverride = $ResourceGroupNameOverride }
}
'AvailabilityZone' { Write-Warning -Message "ResourceGroupNameOverride found $ResourceGroupNameOverride"
$NewITDWindowsVMAzureParams += @{ AvailabilityZone = $AvailabilityZone }
}
}
}
}
Write-Verbose -Message "Connect to Azure using Service Principal" -Verbose
$tenantId = '2dea0464-da51-4a88-bae2-b3db94bc0c54'
$AppId = '60244573-7130-4026-9c6d-47de73f8ca29'
$SecureStringPwd = $Secret:azure_iaasserviceprincipal
$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 "NewITDWindowsVMAzureParams:" -Verbose
Write-Verbose -Message ("ComputerName " + $NewITDWindowsVMAzureParams.ComputerName) -Verbose
Write-Verbose -Message ("CPU " + $NewITDWindowsVMAzureParams.CPU) -Verbose
Write-Verbose -Message ("MemoryGB " + $NewITDWindowsVMAzureParams.MemoryGB) -Verbose
Write-Verbose -Message ("DiskOsGB" + $NewITDWindowsVMAzureParams.DiskOsGB) -Verbose
Write-Verbose -Message ("DiskDataGB " + $NewITDWindowsVMAzureParams.DiskDataGB) -Verbose
Write-Verbose -Message ("Subnet " + $NewITDWindowsVMAzureParams.Subnet) -Verbose
Write-Verbose -Message ("OS" + $NewITDWindowsVMAzureParams.OS) -Verbose
Write-Verbose -Message ("Environment" + $NewITDWindowsVMAzureParams.Environment) -Verbose
Write-Verbose -Message ("AppName" + $NewITDWindowsVMAzureParams.AppName) -Verbose
Write-Verbose -Message ("LicensingRestrictions" + $NewITDWindowsVMAzureParams.LicensingRestrictions) -Verbose
New-ITDWindowsVmAzureStep1 @NewITDWindowsVmAzureParams -Credential $Secret:ndgov_svcitdiaasauto -Verbose
@@ -0,0 +1,75 @@
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTask')]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$FQDN
)
switch ($PSCmdlet.ParameterSetName) {
'ManualEntry' {
$NewITDWindowsVmAzureParams = @{
FQDN = $FQDN;
}
}
'FromSCTask' {
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" { $ServiceNowEnvironment = 'Test' }
"ITDWINAUTOP1" { $ServiceNowEnvironment = 'Production' }
}
Write-Verbose -Message "New-ITDServiceNowSession" -Verbose
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -SysId ($SCTask.request_item.value) -IncludeVariableSet -IncludeCustomVariable
$FqdnFromSCTaskDescription = ($SCTask.short_description).display_value.split(' ')[7]
$NewITDWindowsVmAzureParams = @{
FQDN = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).host_name );
AppName = ( (Get-ITDServiceNowRecord -Table cmdb_ci_service_auto -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).application_info).Name.display_value);
VMEnvironment = ( $Ritm.customvariable.environment.value );
}
}
}
Write-Verbose -Message "Connect to Azure using Service Principal" -Verbose
$tenantId = '2dea0464-da51-4a88-bae2-b3db94bc0c54'
$AppId = '60244573-7130-4026-9c6d-47de73f8ca29'
$SecureStringPwd = $Secret:azure_iaasserviceprincipal
$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 "NewITDWindowsVMAzureParams:" -Verbose
Write-Verbose -Message ("FQDN " + $NewITDWindowsVMAzureParams.FQDN) -Verbose
try {
New-ITDWindowsVmAzureStep2 @NewITDWindowsVmAzureParams -Credential $Secret:ndgov_svcitdiaasauto -Verbose
Write-Warning -Message "New-ITDWindowsVmAzureStep2 function completed"
$Step2Complete = $true
}
catch {
Write-Error -Message $error[0]
$Step2Complete = $false
throw
}
switch ($PSCmdlet.ParameterSetName) {
'FromSCTask' {
switch ($Step2Complete) {
$true {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("Azure build step 2 complete. `nPSU Job Id #" + $UAJob.Id);
}
}
$false {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("Azure build step 2 errored, needs human review. `nPSU Job Id #" + $UAJob.Id)
}
}
}
}
}
@@ -0,0 +1,157 @@
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTask')]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$FQDN,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$CPU = 1,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$MemoryGB = 4,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$DiskOsGB = 50,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$DiskSwapGB = ($MemoryGB + 1),
[Parameter(ParameterSetName = 'ManualEntry')]
[int]
$DiskDataGB,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$Subnet = '10.11.12.0/23',
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$OS = 'Windows Server 2022 Datacenter',
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$VMEnvironment = 'Test',
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$Datacenter = 'Mandan',
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$AppName = 'ITD-POC-zmeier',
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[int]
$StartupPriority = 5,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$LicensingRestrictions = "No Licensing Restrictions"
)
switch ($PSCmdlet.ParameterSetName) {
'ManualEntry' {
$NewITDWindowsVmVMwareParams = @{
FQDN = $FQDN;
CPU = $CPU;
MemoryGB = $MemoryGB;
DiskOsGB = $DiskOsGB;
DiskSwapGB = $DiskSwapGB;
DiskDataGB = $DiskDataGB;
Subnet = $Subnet;
OS = $OS;
VMEnvironment = $VMEnvironment;
Datacenter = $Datacenter;
AppName = $AppName;
StartupPriority = $StartupPriority;
LicensingRestrictions = $LicensingRestrictions;
}
}
'FromSCTask' {
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" { $ServiceNowEnvironment = 'Test' }
"ITDWINAUTOP1" { $ServiceNowEnvironment = 'Production' }
}
Write-Verbose -Message "New-ITDServiceNowSession" -Verbose
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -SysId ($SCTask.request_item.value) -IncludeVariableSet -IncludeCustomVariable
$FqdnFromSCTaskDescription = ($SCTask.short_description).display_value.split(' ')[7]
$NewITDWindowsVmVMwareParams = @{
FQDN = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).host_name );
CPU = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).processors );
MemoryGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).memory_gb );
DiskOsGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).disk_1_os );
DiskSwapGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).disk_2_swap_disk );
DiskDataGB = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).disk_3 );
Subnet = ( Get-ITDServiceNowRecord -Table 'cmdb_ci_ip_network' -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq "$FqdnFromSCTaskDescription" }).cidr_block).name.display_value;
OS = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).target_os_version_windows );
VMEnvironment = ( $Ritm.customvariable.environment.value );
Datacenter = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).data_center );
AppName = ( Get-ITDServiceNowRecord -Table 'cmdb_ci_service' -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq "$FqdnFromSCTaskDescription" }).application_info).name.display_value;
StartupPriority = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).startup_priority );
LicensingRestrictions = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).licensing_restrictions );
}
}
}
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdiaasauto -Verbose
Write-Verbose -Message "Attempt server provisioning" -Verbose
Write-Verbose -Message $NewITDWindowsVmVMwareParams
try {
New-ITDWindowsVmVMwareStep1 @NewITDWindowsVmVMwareParams -Credential $Secret:ndgov_svcitdiaasauto -Verbose
Write-Verbose -Message "New-ITDWindowsVmVMwareStep1 function completed"
$Step1Complete = $true
}
catch {
$Step1Complete = $false
switch ($PSCmdlet.ParameterSetName) {
'FromSCTask' {
$ErrorText = ($_.ErrorDetails.message | ConvertFrom-Json).text
If ($ErrorText -match "Cannot find 1 available IP address" ) {
$Msg = "Resolve the issue and resubmit the Server Build Request catalog item. Setting $SCTaskNum State to Closed Incomplete"
Write-Warning -Message $Msg
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("VMware build step 1 errored. $Msg. `nPSU Job Id #" + $UAJob.Id + " `n" + $ErrorText)
state = 'Closed Incomplete'
}
}
}
}
throw
}
Write-Verbose -Message "Disconnect from vCenter" -Verbose
Disconnect-ITDvCenter
switch ($PSCmdlet.ParameterSetName) {
'FromSCTask' {
Write-Verbose -Message ("Update " + $SCTaskNum + " with Step 1 status") -Verbose
switch ($Step1Complete) {
$true {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("VMware build step 1 complete. `nPSU Job Id #" + $UAJob.Id)
}
}
$false {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("VMware build step 1 errored, needs human review. `nPSU Job Id #" + $UAJob.Id)
}
}
}
}
}
@@ -0,0 +1,87 @@
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTask')]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$FQDN,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$AppName,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$VMEnvironment
)
switch ($PSCMdlet.ParameterSetName) {
'ManualEntry' {
$NewITDWindowsVmVMwareStep2Params = @{
FQDN = $FQDN;
AppName = $AppName;
VMEnvironment = $VMEnvironment;
}
}
'FromSCTask' {
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" { $ServiceNowEnvironment = 'Test' }
"ITDWINAUTOP1" { $ServiceNowEnvironment = 'Production' }
}
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -SysId ($SCTask.request_item.value) -IncludeVariableSet -IncludeCustomVariable
Write-Verbose -Message ("Ritm: " + $Ritm.Number) -Verbose
$FqdnFromSCTaskDescription = ($SCTask.short_description).display_value.split(' ')[7]
Write-Verbose -Message ("FqdnFromSCTaskDescription: " + ($SCTask.short_description).display_value.split(' ')[7] ) -Verbose
$NewITDWindowsVmVMwareStep2Params = @{
FQDN = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).host_name );
VMEnvironment = ( ($Ritm.CustomVariable).environment.value );
AppName = ( (Get-ITDServiceNowRecord -Table cmdb_ci_service_auto -SysId ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).application_info).Name.display_value);
}
Write-Verbose -Message ("Params FQDN: " + $NewITDWindowsVmVMwareStep2Params.FQDN) -Verbose
}
}
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdiaasauto -Verbose
Write-Verbose -Message "Attempt VMware step 2" -Verbose
Write-Host $NewITDWindowsVmVMwareStep2Params
try {
New-ITDWindowsVmVMwareStep2 @NewITDWindowsVmVMwareStep2Params -Credential $Secret:ndgov_svcitdiaasauto -Verbose
Write-Warning -Message "New-ITDWindowsVmVMwareStep2 function completed"
$Step2Complete = $true
}
catch {
Write-Error -Message $error[0]
$Step2Complete = $false
throw
}
Write-Verbose -Message "Disconnect from vCenter" -Verbose
Disconnect-ITDvCenter
switch ($PSCmdlet.ParameterSetName) {
'FromSCTask' {
switch ($Step2Complete) {
$true {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("VM build step 2 complete. `nPSU Job Id #" + $UAJob.Id);
}
}
$false {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("VMware build step 2 errored, needs human review. `nPSU Job Id #" + $UAJob.Id)
}
}
}
}
}
@@ -0,0 +1,146 @@
<#
.SYNOPSIS
Processes automated server build tasks for Windows machines in ServiceNow, triggered via PowerShell Universal.
.DESCRIPTION
This script connects to the ServiceNow API, retrieves open catalog tasks that match a specific filter for automated server build tasks,
and processes them. This script is designed to run as a scheduled task. It can optionally filter tasks by a specific SCTask number.
.PARAMETER SCTaskNum
The ServiceNow task number to filter the tasks. If not provided, all tasks matching the filter will be processed.
.EXAMPLE
.\New-ITDWindowsVmBuildTask_Auto.ps1
This example runs the script and processes all open tasks that match the filter for automated server build tasks.
.EXAMPLE
.\New-ITDWindowsVmBuildTask_Auto.ps1 -SCTaskNum 'SCTASK0012345'
This example runs the script and processes only the task with the specified SCTask number.
.NOTES
Ensure that the ServiceNow instance URL and credentials are correctly configured in the New-ITDServiceNowSession function.
This script is not supported in Linux.
#>
Param(
[string]
$SCTaskNum
)
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$Filter = 'active=true^short_descriptionSTARTSWITHAutomated Server Build Task for Windows Machine'
$OpenTasks = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Filter $Filter -IncludeTotalCount | Sort-Object Number
If ($PSBoundParameters.ContainsKey("SCTaskNum")) {
Write-Verbose -Message "SCTaskNum parameter found, value is $SCTaskNum" -Verbose
$OpenTasks = $OpenTasks | Where-Object { $_.number.value -EQ $SCTaskNum }
}
$AllRitms = [System.Collections.ArrayList]@()
Write-Verbose -Message ("OpenTasks found: " + @($OpenTasks).Count) -Verbose
ForEach ($OpenTask in $OpenTasks) {
$PSUJob = $null
$SCTask = $null
$shortdescription = $null
$shortdescription_hostname = $null
$WorkNotesMsg = $null
$SCTaskNum = $OpenTask.number.Value
Write-Verbose -Message "Start $SCTaskNum" -Verbose
try {
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$shortdescription = $SCTask.short_description.display_value
$shortdescription_hostname = $shortdescription.split(' ')[7]
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $SCTask.request_item.display_value -IncludeVariableSet
<#
If ($AllRitms | Where-Object { $_.number.display_value -EQ $SCTask.request_item.display_value }) {
Write-Verbose -Message ("Ritm already in memory") -Verbose
$Ritm = $AllRitms | Where-Object sys_id -EQ $SCTask.request_item.display_value
}
Else {
Write-Verbose -Message "Ritm is not in memory, retrieve it" -Verbose
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $SCTask.request_item.display_value -IncludeVariableSet
$null = $AllRitms.Add($Ritm)
}
#>
# check for step messages in SCTask work_notes and determine next step
switch ($SCTask.work_notes.display_value) {
{ $_ -match "human review" } {
Write-Verbose -Message "Human review required, skipping" -Verbose
Break
}
{ $_ -match "build step 2 complete" } {
# execute Step 3
Write-Verbose -Message "Step 2 already complete, starting step 3" -Verbose
$PSUJob = Invoke-PSUScript -Script "New-ITDWindowsVm_Step3.ps1" -SCTaskNum $SCTaskNum
#$WorkNotesMsg = ("VMware build Step 3 started.`nPSU Job Id #" + $PSUJob.Id)
Break
}
{ $_ -match "build Step 2 started"} {
Write-Verbose -Message "Step 2 already started, skipping" -Verbose
Break
}
{ $_ -match "build step 1 complete" } {
# execute Step 2
Write-Verbose -Message "Step 1 already complete, starting Step 2" -Verbose
# Determine if VMware or Azure and run appropriate build Step 2 function
switch ( ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).target_platform ) {
'azure' {
$target_platform = "Azure"
Write-Verbose "Invoking PSUScript for Azure Step 2" -Verbose
$PSUJob = Invoke-PSUScript -Script "New-ITDWindowsVmAzure_Step2.ps1" -SCTaskNum $SCTaskNum
$WorkNotesMsg = ("Azure build Step 2 started.`nPSU Job Id #" + $PSUJob.Id)
}
'vmware' {
$target_platform = "VMware"
Write-Verbose "Invoking PSUScript for VMware Step 2" -Verbose
$PSUJob = Invoke-PSUScript -Script "New-ITDWindowsVmVMware_Step2.ps1" -SCTaskNum $SCTaskNum
$WorkNotesMsg = ("VMware build Step 2 started.`nPSU Job Id #" + $PSUJob.Id)
}
}
Break
}
{ $_ -match "build Step 1 started"} {
Write-Verbose -Message "Step 1 already started, skipping" -Verbose
Break
}
Default {
# execute Step 1
Write-Verbose -Message "No step messages found, starting Step 1" -Verbose
# Determine if VMware or Azure and run appropriate build function
switch ( ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).target_platform ) {
'azure' {
$target_platform = "Azure"
Write-Verbose "Invoking PSUScript for Azure Step 1" -Verbose
$PSUJob = Invoke-PSUScript -Script "New-ITDWindowsVmAzure_Step1.ps1" -SCTaskNum $SCTaskNum
$WorkNotesMsg = ("Azure build Step 1 started.`nPSU Job Id #" + $PSUJob.Id)
}
'vmware' {
$target_platform = "VMware"
Write-Verbose "Invoking PSUScript for VMware Step 1" -Verbose
$PSUJob = Invoke-PSUScript -Script "New-ITDWindowsVmVMware_Step1.ps1" -SCTaskNum $SCTaskNum
$WorkNotesMsg = ("VMware build Step 1 started.`nPSU Job Id #" + $PSUJob.Id)
}
}
Break
}
}
}
catch {
Write-Error -Message $error[0]
}
If($null -eq $WorkNotesMsg){
# do nothing
} Else {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{work_notes = $WorkNotesMsg }
}
Write-Verbose -Message "End $SCTaskNum" -Verbose
}
#>
#Invoke-PSUScript -Name New-ITDWindowsVmVMware_Step1.ps1 -SCTaskNum "SCTASK0310457"
@@ -0,0 +1,126 @@
# used by both Azure and VMware build tasks
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTASK')]
[string]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$FQDN
)
# get FQDN from SCTask/Ritm, or directly from user input
switch ($PSCmdlet.ParameterSetName) {
'ManualEntry' {
Write-Verbose -Message "FQDN manually entered"
}
'FromSCTask' {
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" { $ServiceNowEnvironment = 'Test' }
"ITDWINAUTOP1" { $ServiceNowEnvironment = 'Production' }
}
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -SysId ($SCTask.request_item.value) -IncludeVariableSet -IncludeCustomVariable
Write-Verbose -Message ("Ritm: " + $Ritm.Number) -Verbose
$FqdnFromSCTaskDescription = ($SCTask.short_description).display_value.split(' ')[7]
Write-Verbose -Message ("FqdnFromSCTaskDescription: " + ($SCTask.short_description).display_value.split(' ')[7] ) -Verbose
$FQDN = ( ($Ritm.VariableSet | Where-Object { $_.host_name -eq $FqdnFromSCTaskDescription }).host_name ).tolower();
$OperatingSystem = ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).operating_system
}
}
try {
switch ( ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).target_platform ) {
'azure' { $target_platform = "Azure" }
'vmware' { $target_platform = "VMware" }
}
<# Is this needed?
$Ci = Get-ITDServiceNowRecord -Table cmdb_ci -Filter ("name=" + $FormHostName)
If ($Ci) {
Write-Verbose -Message ("Ci found, sys_id = " + $Ci.sys_id + ", name = " + $Ci.name + ", fqdn = " + $Ci.fqdn) -Verbose
}
Else {
# Ci does not exist
Write-Verbose -Message ("Ci not found") -Verbose
}
switch ($Ci.model_id.display_value) {
{ $_ -like "*VMware*" } { $hardware_platform = "VMware"; $hardware_type = 'Virtual Machine' }
{ $_ -like "*Microsoft Virtual Machine*" } { $hardware_platform = "Azure"; $hardware_type = 'Virtual Machine' }
{ $_ -like "*HP*" } { $hardware_platform = 'HPE'; $hardware_type = 'Physical' }
default { $hardware_platform = 'Other' }
}
#>
Write-Verbose -Message "Confirm all required agents are running"
$ProcessList = @('ccmexec', 'cohesity*', 'nessus*', 'cortex*')
switch ($target_platform) {
'VMware' {
$ProcessList += 'vmtoolsd'
}
'Azure' {
Write-Verbose -Message "No Azure specific agents to check for" -Verbose
}
Default {
Write-Verbose -Message "no Ci means no platform check"
}
}
}
catch {
Write-Error $error[0]
}
If ( $FQDN -like "*.nd.gov" ) {
try {
$AgentCount = 0
$svcitdpsuwin = Get-ITDPassword -UserName ndgov\svcitdpsuwin -Title ndgov\svcitdpsuwin
$RunningProcess = Invoke-Command -Credential $svcitdpsuwin -ComputerName $FQDN -ErrorAction Stop -ScriptBlock {
Get-Process
}
If ($RunningProcess) {
ForEach ($ProcessName in $ProcessList) {
If ($RunningProcess -match $ProcessName) {
Write-Verbose -Message "Process $ProcessName found." -Verbose
$AgentCount = $AgentCount + 1
}
Else {
Write-Warning -Message "Process $ProcessName not found"
# do not increase agentcount count
}
}
}
}
catch [System.Management.Automation.Remoting.PSRemotingTransportException] {
Write-Warning -Message "$FQDN unreachable via PSRemoting"
$BuildComplete = $false
}
}
Else {
Write-Verbose -Message ($SCTaskNum + $ComputerName + " is not nd.gov, manual agent validation required.") -Verbose
}
If ($AgentCount -ge @($ProcessList).count) {
Write-Verbose "All required processes running, Windows is ready for use. Update SCTask to notify physical/virtual hardware stakeholders." -Verbose
$work_notes = ("$target_platform $hardware_type $FQDN Windows Guest OS complete. `nPSU Job Id #" + $UAJob.Id)
$shortdescription = "$target_platform $hardware_type $FQDN Windows Guest OS complete."
Write-Verbose -Message "Work notes: $work_notes" -Verbose
Write-Verbose -Message "Short description: $shortdescription" -Verbose
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = $work_notes;
close_notes = "$FQDN $target_platform Windows Guest OS complete.";
short_description = $shortdescription;
state = 'Closed Complete'
}
}
Write-Verbose -Message "End $SCTasknum" -Verbose
@@ -0,0 +1,92 @@
param(
[string]
$SCTaskNum
)
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$Filter = "active=true^short_descriptionLIKEWindows Removal for "
$OpenTasks = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Filter $Filter -IncludeTotalCount | Sort-Object { $_.Number.value }
If ($PSBoundParameters.ContainsKey("SCTaskNum")) {
Write-Verbose -Message "SCTaskNum parameter found, value is $SCTaskNum"
$OpenTasks = $OpenTasks | Where-Object { $_.number.value -EQ $SCTaskNum }
}
$AllRitms = [System.Collections.ArrayList]@()
Write-Verbose -Message ("Number of OpenTasks is " + @($OpenTasks).count) -Verbose
# retrieve ndgov\svcitdiaasauto password to be used for Remove-ITDWindowsServer function
$svcitdiaasauto = Get-ITDPassword -Title "IaaS Automation Account" -UserName "ndgov\svcitdiaasauto"
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter
ForEach ($OpenTask in $OpenTasks) {
# get SCTask, Ritm
$SCTask = $OpenTask
$SCTaskNum = $OpenTask.number.display_value
Write-Verbose -Message ("Start " + $SCTaskNum) -Verbose
If ($SCTask.work_notes.display_value -like "*needs human review*") {
Write-Verbose -Message ($SCTaskNum + " flagged for human review, skipping...") -Verbose
}
Else {
$short_description = $SCTask.short_description.display_value
$short_description_hostname = $short_description.split(' ')[4]
$RitmNum = $SCTask.request_item.display_value
If ($AllRitms | Where-Object sys_id -EQ $SCTask.request_item.value) {
$Ritm = $AllRitms | Where-Object sys_id -EQ $SCTask.request_item.display_value
}
Else {
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $SCTask.request_item.display_value -IncludeVariableSet
$null = $AllRitms.Add($Ritm)
}
#$Ci = Get-ITDServiceNowRecord -Table cmdb_ci -Filter ("name=" + $short_description_hostname)
#$Ci = Get-ITDServiceNowRecord -Table cmdb_ci -SysId ($Ritm.VariableSet | Where-Object .host_name_ref) -ErrorAction Stop
Write-Verbose -Message "Gathering VariableSet data from $RitmNum"
$MatchFound = $false
ForEach ($Row in $Ritm.VariableSet) {
$TempCi = Get-ITDServiceNowRecord -Table cmdb_ci -SysId ($Row.host_name_ref) -ErrorAction Stop
If ($short_description_hostname -eq $TempCi.FQDN.display_value) {
$Ci = $TempCi
$MatchFound = $true
}
}
If ($MatchFound -eq $false) {
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = 'error during Windows decommission, needs human review'
}
Write-Warning -Message "ComputerName $ComputerName was not found in VariableSet for $RitmNum" -WarningAction Continue
}
$HostName = $Ci.Name.display_value
$FQDN = $Ci.FQDN.display_value
Write-Verbose -Message ("Ci Name " + $Ci.Name.display_value) -Verbose
Write-Verbose -Message ("Ci FQDN " + $Ci.FQDN.display_value) -Verbose
switch ($Ci.model_id.display_value) {
{ $_ -like "*VMware*" } { $hardware_platform = "VMware"; $hardware_type = 'Virtual Machine' }
{ $_ -like "*Microsoft Virtual Machine*" } { $hardware_platform = "Azure"; $hardware_type = 'Virtual Machine' }
{ $_ -like "*HP*" } { $hardware_platform = 'HPE'; $hardware_type = 'Physical' }
default { $hardware_platform = 'Unknown'; $hardware_type = 'Other' }
}
try {
Write-Verbose -Message "Start Removal of $FQDN, $hardware_platform $hardware_type" -Verbose
Remove-ITDWindowsServer -ComputerName $FQDN -SCTaskNum $SCTaskNum -Credential $svcitdiaasauto -Verbose
Write-Verbose -Message "End Removal of $FQDN" -Verbose
}
catch {
Write-Error $error[0]
}
Write-Verbose -Message "End $SCTasknum" -Verbose
}
}
Write-Verbose -Message "Disconnect to vCenter" -Verbose
Disconnect-ITDvCenter