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,7 @@
Param (
[string]
$Number
)
Write-Output @{Number = $Number}
@@ -0,0 +1,17 @@
New-PSUAccessControl -Role "Team-Windows" -Type "View, Execute" -Tag "Team-Windows_Execute"
New-PSUAccessControl -Role "Team-Windows" -Type "View, Edit, Create, Delete, Execute" -Tag "Team-Windows_Modify"
New-PSUAccessControl -Role "Team-Network" -Type "View, Execute" -Tag "Team-Network_Execute"
New-PSUAccessControl -Role "Team-Linux" -Type "View, Execute" -Tag "Team-Linux_Execute"
New-PSUAccessControl -Role "Team-ConnectND" -Type "View, Execute" -Tag "Team-CND_Execute"
New-PSUAccessControl -Role "Team-Tier2" -Type "View, Execute" -Tag "Team-Tier2_Execute"
New-PSUAccessControl -Role "Team-Mgmt" -Type "View, Execute" -Tag "Team-Mgmt_Execute"
New-PSUAccessControl -Role "Team-Mgmt" -Type "View, Edit, Create, Delete, Execute" -Tag "Team-Mgmt_Modify"
New-PSUAccessControl -Role "App-Infra-VMware" -Type "View, Execute" -Tag "Infra-VMware_Execute"
New-PSUAccessControl -Role "App-Infra-VMware" -Type "View, Edit, Create, Delete, Execute" -Tag "Infra-VMware_Modify"
New-PSUAccessControl -Role "App-ITD-WindowsServer" -Type "View, Execute" -Tag "ITD-WindowsServer_Execute"
New-PSUAccessControl -Role "App-ITD-WindowsServer" -Type "View, Edit, Create, Delete, Execute" -Tag "ITD-WindowsServer_Modify"
New-PSUAccessControl -Role "App-Shared-PowerSchool" -Type "View, Execute" -Tag "Shared-PowerSchool_Execute"
New-PSUAccessControl -Role "App-Shared-PowerSchool" -Type "View, Edit, Create, Delete, Execute" -Tag "Shared-PowerSchool_Modify"
New-PSUAccessControl -Role "Team-Collaboration" -Type "View, Execute" -Tag "Team-Collaboration_Execute"
New-PSUAccessControl -Role "Team-Collaboration" -Type "View, Edit, Create, Delete, Execute" -Tag "Team-Collaboration_Modify"
New-PSUAccessControl -Role "App-Infra-Certificate" -Type "View, Edit, Execute" -Tag "Infra-Certificate_Modify"
@@ -0,0 +1,87 @@
Set-PSUAuthenticationMethod -Type "Form" -ScriptBlock {
param(
[PSCredential]$Credential
)
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
# is this a UPN?
if ( $Credential.UserName.IndexOf('@') -gt -1 ) {
# juggle back and forth from SID to get NTAccount format
$NTAccountName = ([System.Security.Principal.NTAccount]$Credential.UserName).Translate([System.Security.Principal.SecurityIdentifier]).Translate([System.Security.Principal.NTAccount]).Value
} elseif ( $Credential.UserName.IndexOf('\') -gt -1 ) {
# already NTAccount format
$NTAccountName = $Credential.UserName
} else {
# someone didn't enter their domain...
$NTAccountName = "NDGOV\" + $Credential.GetNetworkCredential().UserName
}
# split domain and username
$DomainName, $UserName = $NTAccountName.Split('\',2)
# perform auth with AD
$PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext( 'Domain', $DomainName )
$Authenticated = $PrincipalContext.ValidateCredentials( $UserName, $Credential.GetNetworkCredential().Password, 'Negotiate, Sealing' )
if ( $Authenticated ) {
# discover the user principal, needed for the user DN
$UserPrincipal = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($PrincipalContext, [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName, $NTAccountName )
# get the user's domain
$UserDomainContext = [System.DirectoryServices.ActiveDirectory.DirectoryContext]::new( 'Domain', $DomainName, $Credential.UserName, $Credential.GetNetworkCredential().Password )
$UserDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain( $UserDomainContext )
# get the computer's domain
#$ComputerDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()
# hold all the user groups
[System.Collections.Generic.List[hashtable]]$Groups = @()
# get groups from user's domain
#[adsisearcher]::new( $UserDomain.GetDirectoryEntry(), "(&(objectCategory=group)(objectClass=group)(member:1.2.840.113556.1.4.1941:=$($UserPrincipal.DistinguishedName)))", @('name') ).FindAll().ForEach({
[adsisearcher]::new( $UserDomain.GetDirectoryEntry(), "(&(objectCategory=group)(objectClass=group)(member:1.2.840.113556.1.4.1941:=$($UserPrincipal.DistinguishedName))(name=ITD-PSUniversal-*))", @('name') ).FindAll().ForEach({
$Groups.Add(@{
Type = 'Group'
Value = $_.Properties['name'][0]
Issuer = $UserDomain.Name
})
})
<#
# get groups from the computer's domain (if different)
if ( $UserDomain.Name -ne $ComputerDomain.Name ) {
# lookup the user's foreign security principal in the computer's domain
$ForeignSecurityPrincipal = [adsisearcher]::new( $ComputerDomain.GetDirectoryEntry(), "(&(objectCategory=foreignSecurityPrincipal)(objectClass=foreignSecurityPrincipal)(name=$($UserPrincipal.Sid)))", @('distinguishedName') ).FindOne().Properties['distinguishedName'][0]
# find all the group memberships
[adsisearcher]::new( $ComputerDomain.GetDirectoryEntry(), "(&(objectCategory=group)(objectClass=group)(member:1.2.840.113556.1.4.1941:=$ForeignSecurityPrincipal))", @('name') ).FindAll().ForEach({
$Groups.Add(@{
Type = 'Group'
Value = $_.Properties['name'][0]
Issuer = $ComputerDomain.Name
})
})
}
#>
New-PSUAuthenticationResult -Success -UserName $UserPrincipal.UserPrincipalName -Claims {
$Groups | ForEach-Object { New-PSUAuthorizationClaim @_ }
}
} else {
New-PSUAuthenticationResult -ErrorMessage 'Bad username or password :)'
}
}
Set-PSUAuthenticationMethod -Type "Windows" -Disabled
@@ -0,0 +1,6 @@
New-PSUApp -Name "PSUVariableReview" -FilePath "dashboards\PSUVariableReview\PSUVariableReview.ps1" -BaseUrl "/PSUVariableReview" -Authenticated -AutoDeploy
New-PSUApp -Name "Infra-VMware_Snapshot" -FilePath "dashboards\Infra-VMware_Snapshot\Infra-VMware_Snapshot.ps1" -BaseUrl "/Infra-VMware_Snapshot" -Authenticated -AutoDeploy
New-PSUApp -Name "ServiceNowDumps" -FilePath "dashboards\ServiceNowDumps\ServiceNowDumps.ps1" -BaseUrl "/ServiceNowDumps" -Authenticated -AutoDeploy
New-PSUApp -Name "NewITDADServiceAccount" -FilePath "dashboards\NewITDADServiceAccount\NewITDADServiceAccount.ps1" -BaseUrl "/NewITDADServiceAccount" -Authenticated -AutoDeploy
New-PSUApp -Name "ITD-WindowsServer_FileManagement" -FilePath "dashboards\ITD-WindowsServer_FileManagement\ITD-WindowsServer_FileManagement.ps1" -BaseUrl "/ITD-WindowsServer_FileManagement" -Authenticated -AutoDeploy
New-PSUApp -Name "ServiceNow" -FilePath "dashboards\ServiceNow\ServiceNow.ps1" -BaseUrl "/ServiceNow" -Authenticated -AutoDeploy
@@ -0,0 +1 @@
New-PSUEndpoint -Url "/Get-ITDServiceNowRecord" -Method @('GET') -Authentication -Path "Get-ITDServiceNowRecord" -Tag @('Infra-VMware_Execute','Team-Windows_Execute','Infra-VMware_Modify','Team-Windows_Modify')
@@ -0,0 +1,15 @@
$Parameters = @{
Image = "/PSUniversal_Extras/logo.png"
Title = "PowerShell Universal"
Links = @(
New-PSULoginPageLink -Text 'ServiceNow' -Url 'https://northdakota.service-now.com/'
New-PSULoginPageLink -Text 'VMware vCenter' -Url 'https://itdvmvc1.nd.gov/ui'
New-PSULoginPageLink -Text 'Microsoft Azure' -Url 'https://portal.azure.com'
New-PSULoginPageLink -Text 'Passwordstate' -Url 'https://itdpv.nd.gov'
New-PSULoginPageLink -Text 'Solarwinds' -Url 'https://solarwinds.nd.gov/'
New-PSULoginPageLink -Text 'Panorama' -Url 'https://panorama-gov.nd.gov/php/login.php'
New-PSULoginPageLink -Text 'Ansible' -Url 'https://ansible.nd.gov/#/login'
New-PSULoginPageLink -Text 'Confluence Wiki' -Url 'https://wiki.nd.gov/i/dashboard.action'
)
}
New-PSULoginPage @Parameters
@@ -0,0 +1 @@
New-PSUPublishedFolder -RequestPath "/PSUniversal_Extras" -Path "E:\PSUniversal_Extras" -Name "PSUniversal_Extras"
@@ -0,0 +1,149 @@
New-PSURole -Name "Administrator" -Description "Administrators can manage settings, create and edit any entity and view all the entities with PowerShell Universal." -Policy {
param(
[Security.ClaimsPrincipal]$User
)
<#
Policies should return $true or $false to determine whether the user has the particular
claim that require them for that role.
#>
#$false
<#
$UserName = ($User.Identity.Name)
$UserName = $UserName.Substring($UserName.IndexOf('\') + 1, ($UserName.Length - ($UserName.IndexOf('\') + 1)))
$IsMember = $false;
# Perform LDAP Group Member Lookup
$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = 'LDAP://OU=USERS, OU=ITD, DC=nd, DC=gov' # INSERT ROOT LDAP HERE
$Searcher.Filter = "(&(objectCategory=person)(memberOf=CN=ITD-PSUniversal-Admin,OU=ITDGROUPS,OU=GROUPS,OU=ITD,DC=nd,DC=gov))" #GROUP INSERT DN TO CHECK HERE
$Users = $Searcher.FindAll()
$Users | ForEach-Object {
If ($_.Properties.samaccountname -eq $UserName) {
$IsMember = $true;
"$UserName is a member of admin group!" | Out-File "C:\test\adgroup.txt"
}
else {
"$UserName is NOT member of admin group!" | Out-File "C:\test\adgroup.txt"
}
}
return $IsMember
#>
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains 'ITD-PSUniversal-Admin'
}
New-PSURole -Name "Operator" -Description "Operators have access to manage and execute scripts, create other entities within PowerShell Universal but cannot manage PowerShell Universal itself." -Policy {
param(
[Security.ClaimsPrincipal]$User
)
<#
Policies should return $true or $false to determine whether the user has the particular
claim that require them for that role.
#>
#$false
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains 'ITD-PSUniversal-Operator'
}
New-PSURole -Name "Reader" -Description "Readers have read-only access to PowerShell Universal. They cannot make changes to any entity within the system." -Policy {
param(
[Security.ClaimsPrincipal]
$User
)
<#
Policies should return $true or $false to determine whether the user has the particular
claim that require them for that role.
#>
$User | ConvertTo-Json | Set-Content ("C:\temp\user-" + $User.Identity.Name + ".json")
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -match "ITD-PSUniversal-*"
}
New-PSURole -Name "Execute" -Description "Execute scripts within PowerShell Universal." -Policy {
param(
[Security.ClaimsPrincipal]$User
)
<#
Policies should return $true or $false to determine whether the user has the particular
claim that require them for that role.
#>
$false
}
New-PSURole -Name "User" -Description "Does not have access to the admin console but can be assigned resources like APIs, scripts, dashboards and pages." -Policy {
param(
[Security.ClaimsPrincipal]$User
)
<#
Policies should return $true or $false to determine whether the user has the particular
claim that require them for that role.
#>
$false
}
New-PSURole -Name "Team-Windows" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-Team-Windows"
}
New-PSURole -Name "Team-Linux" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-Team-Linux"
}
New-PSURole -Name "Team-ConnectND" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-Team-ConnectND"
}
New-PSURole -Name "Team-Network" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-Team-Network"
}
New-PSURole -Name "Team-Tier2" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-Team-Tier2"
}
New-PSURole -Name "Team-Mgmt" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-Team-Mgmt"
}
New-PSURole -Name "App-Infra-VMware" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-App-Infra-VMware"
}
New-PSURole -Name "App-ITD-WindowsServer" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-App-ITD-WindowsServer"
}
New-PSURole -Name "App-Shared-Powerschool" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-App-Shared-PowerSchool"
}
New-PSURole -Name "Team-Collaboration" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-Team-Collaboration"
}
New-PSURole -Name "App-Infra-Certificate" -Policy {
param($User)
$Roles = $User.Claims | Where-Object Type -EQ Group | Select-Object -ExpandProperty Value
$Roles -contains "ITD-PSUniversal-App-Infra-Certificate"
}
@@ -0,0 +1,27 @@
New-PSUSchedule -Cron "*/20 * * * *" -Script "Infra-VMware.Snapshot\Update-ITDVMwareVMSnapshotStatus.ps1" -TimeZone "America/Chicago" -Name "Update-ITDVMwareVMSnapshotStatus" -RandomDelay
New-PSUSchedule -Cron "* * * * *" -Script "ZM-Test\Test-ITDSchedule.ps1" -TimeZone "America/Chicago" -Credential "ndgov_svcitdvmvcauto" -Environment "Agent" -Name "ZM-Test\Test-ITDSchedule" -Paused
New-PSUSchedule -Cron "0 * * * *" -Script "Infra-VMware.Snapshot\Remove-ITDVMwareVMSnapshotExpired.ps1" -TimeZone "America/Chicago" -Name "Remove-ITDVMwareVMSnapshotExpired" -RandomDelay
New-PSUSchedule -Cron "0 */1 * * *" -Script "Infra-VMware.VirtualMachine\Sync-ITDServerBuildRITMs.ps1" -TimeZone "America/Chicago" -Name "Sync-ITDServerBuildRITMs.ps1" -RandomDelay -RandomDelayMaximum 600
New-PSUSchedule -Cron "*/20 * * * *" -Script "Infra-VMware.VirtualMachine\Update-ITDSnowVMTaskDescription.ps1" -TimeZone "America/Chicago" -Name "Update-ITDSnowVMTaskDescription" -RandomDelay
New-PSUSchedule -Cron "13 8-17 * * *" -Script "Infra-Servers-PowerShellUniversal\Update-ITDModule.ps1" -TimeZone "America/Chicago" -Name "Update-ITDModule.ps1" -RandomDelay -RandomDelayMaximum 600
New-PSUSchedule -Cron "27 8-16/2 * * 1-5" -Script "ITD-WindowsServer.Lifecycle\Remove-ITDWindowsServer.ps1" -TimeZone "America/Chicago" -Name "Remove-ITDWindowsServer" -RandomDelay -RandomDelayMaximum 300
New-PSUSchedule -Cron "23 * * * *" -Script "Infra-VMware.VirtualMachine\Sync-ITDVMwareVMTagsFromCmdb.ps1" -TimeZone "America/Chicago" -Name "Sync-ITDVMwareVMTagsFromCmdb"
New-PSUSchedule -Cron "7/30 8-16 * * *" -Script "ITD-WindowsServer.Lifecycle\New-ITDWindowsVm_Auto.ps1" -TimeZone "America/Chicago" -Name "New-ITDWindowsVm_Auto"
New-PSUSchedule -Cron "0 13 * * 1-5" -Script "Infra-VMware.VirtualMachine\Move-ITDVMwareVMToAppNameFolder_Auto.ps1" -TimeZone "America/Chicago" -Parameters @{
All = $true
} -Name "Move-ITDVMwareVMToAppNameFolder_Auto"
New-PSUSchedule -Cron "33 8-16/2 * * *" -Script "Infra-VMware.VirtualMachine\Set-ITDVMwareVMTagFromCmdb.ps1" -TimeZone "America/Chicago" -Parameters @{
NewBuilds = $true
} -Name "Set-ITDVMwareVMTagFromCmdb_NewBuilds"
New-PSUSchedule -Cron "4 8 * * MON-FRI" -Script "Infra-VMware.VirtualMachine\Set-ITDVMwareVMTagFromCmdb.ps1" -TimeZone "America/Chicago" -Parameters @{
All = $true
} -Name "Set-ITDVMwareVMTagFromCmdb_All"
New-PSUSchedule -Cron "0 0 * * *" -Script "ZM-Test\Test-ITDScheduleWithCreds.ps1" -TimeZone "America/Chicago" -Name "Test-ITDScheduleWithCreds.ps1"
New-PSUSchedule -Cron "15 10 * * MON-FRI" -Script "Infra-VMware.Administration\Update-ITDVMwareILOSslCertificate.ps1" -TimeZone "America/Chicago" -Parameters @{
SynergyDiscovery = $true
} -Name "Update-ITDVMwareILOSslCertificate.ps1"
New-PSUSchedule -Cron "0 11 * * *" -Script "Infra-Certificate-External.Sectigo\Invoke-CertAutoRenew.ps1" -TimeZone "America/Chicago" -Name "Invoke-CertAutoReview.ps1"
New-PSUSchedule -Cron "0 8 * * *" -Script "Infra-VMware.Administration\Sync-ITDVMwareVMMetadataToSql.ps1" -TimeZone "America/Chicago" -Name "Sync-ITDVMwareVMMetadataToSql.ps1"
New-PSUSchedule -Cron "0 8 * * *" -Script "Infra-VMware.Administration\Sync-ITDVMwareHostMetadataToSql.ps1" -TimeZone "America/Chicago" -Name "Sync-ITDVMwareHostMetadataToSql.ps1"
New-PSUSchedule -Cron "0 8 * * *" -Script "Infra-VMware.Administration\Sync-ITDVMwareClusterMetadataToSql.ps1" -TimeZone "America/Chicago" -Name "Sync-ITDVMwareClusterMetadataToSql.ps1"
New-PSUSchedule -Cron "0 8 * * *" -Script "Infra-VMware.Administration\Sync-ITDOneViewServerInventoryToSql.ps1" -Name "Sync-ITDOneViewServerInventoryToSql.ps1"
@@ -0,0 +1,56 @@
New-PSUScript -Name "New-ITDPSUScript.ps1" -Description "New-ITDPSUScript.ps1" -Tag @('Infra-VMware_Execute','Team-Windows_Execute') -Path "Infra-Servers-PowerShellUniversal\New-ITDPSUScript.ps1" -Environment "Integrated"
New-PSUScript -Name "New-ITDVMwareVMSnapshotTask.ps1" -Description "New-ITDVMwareVMSnapshotTask.ps1" -Tag @('Team-Windows_Execute','Team-Network_Execute','Infra-VMware_Modify','Team-Linux_Execute','Team-CND_Execute','Team-Tier2_Execute','Team-Collaboration_Execute') -Path "Infra-VMware.Snapshot\New-ITDVMwareVMSnapshotTask.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdvmsnapmgr"
New-PSUScript -Name "Update-ITDVMwareVMSnapshotStatus.ps1" -Description "Update-ITDVMwareVMSnapshotStatus.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Snapshot\Update-ITDVMwareVMSnapshotStatus.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdvmsnapmgr"
New-PSUScript -Name "Remove-ITDVMwareVMSnapshotExpired.ps1" -Description "Remove-ITDVMwareVMSnapshotExpired.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Snapshot\Remove-ITDVMwareVMSnapshotExpired.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdvmsnapmgr"
New-PSUScript -Name "Test-ITDSchedule.ps1" -Description "Test-ITDSchedule.ps1" -Tag @('Infra-VMware_Modify') -Path "ZM-Test\Test-ITDSchedule.ps1"
New-PSUScript -Name "New-ITDADServiceAccount.ps1" -Description "New-ITDADServiceAccount.ps1" -Tag @('Team-Windows_Execute','ITD-WindowsServer_Modify') -Path "Infra-ActiveDirectory.Object\New-ITDADServiceAccount.ps1" -Environment "Agent" -ErrorAction "Stop" -Credential "ndgov_svcitdpsuad"
New-PSUScript -Name "Approve-ITDWindowsServer.ps1" -Description "Approve-ITDWindowsServer.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.General\Approve-ITDWindowsServer.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Remove-ITDWindowsServer.ps1" -Description "Remove-ITDWindowsServer.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.Lifecycle\Remove-ITDWindowsServer.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Update-ITDModule.ps1" -Description "Update-ITDModule.ps1" -Tag @('Infra-VMware_Execute','Team-Windows_Execute','Infra-VMware_Modify') -Path "Infra-Servers-PowerShellUniversal\Update-ITDModule.ps1" -Environment "7.4.13"
New-PSUScript -Name "Sync-ITDVMwareVMMetadataToSharePoint.ps1" -Description "Sync-ITDVMwareVMMetadataToSharePoint.ps1" -Tag @('Infra-VMware_Modify','Team-Mgmt_Execute') -Path "Infra-VMware.VirtualMachine\Sync-ITDVMwareVMMetadataToSharePoint.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaassprw"
New-PSUScript -Name "Sync-ITDServerBuildRITMs.ps1" -Description "Sync-ITDServerBuildRITMs.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.VirtualMachine\Sync-ITDServerBuildRITMs.ps1" -Environment "Agent"
New-PSUScript -Name "Update-ITDSnowVMTaskDescription.ps1" -Description "Update-ITDSnowVMTaskDescription.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.VirtualMachine\Update-ITDSnowVMTaskDescription.ps1" -Environment "Agent" -ErrorAction "Stop"
New-PSUScript -Name "Add-ITDADUserSPN.ps1" -Description "Add-ITDADUserSPN.ps1" -Tag @('Team-Windows_Execute','ITD-WindowsServer_Modify') -Path "Infra-ActiveDirectory.Object\Add-ITDADUserSPN.ps1" -Environment "Agent" -ErrorAction "Stop" -Credential "ndgov_svcitdpsuad"
New-PSUScript -Name "New-ITDWindowsVmVMware_Manual.ps1" -Description "New-ITDWindowsVmVMware_Manual.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.General\New-ITDWindowsVmVMware_Manual.ps1" -Environment "Agent" -DisableManualInvocation -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "New-ITDWindowsVmAzure_Manual.ps1" -Description "New-ITDWindowsVmAzure_Manual.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.General\New-ITDWindowsVmAzure_Manual.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Get-ITDVMwareVMGuestIPsForPA.ps1" -Description "Get-ITDVMwareVMGuestIPsForPA.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Administration\Get-ITDVMwareVMGuestIPsForPA.ps1"
New-PSUScript -Name "Test-PSUVariable.ps1" -Description "Test-PSUVariable.ps1" -Tag @('Infra-VMware_Execute') -Path "ZM-Test\Test-PSUVariable.ps1"
New-PSUScript -Name "Get-ITDVMwareLunIdNextAvailable.ps1" -Description "Get-ITDVMwareLunIdNextAvailable.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Administration\Get-ITDVMwareLunIdNextAvailable.ps1"
New-PSUScript -Name "Update-ITDSolarwindsNodeFromSNowRitm.ps1" -Description "Update-ITDSolarwindsNodeFromSNowRitm.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "Infra-Monitoring-Solarwinds\Update-ITDSolarwindsNodeFromSNowRitm.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Add-ITDSolarwindsNode.ps1" -Description "Add-ITDSolarwindsNode.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "Infra-Monitoring-Solarwinds\Add-ITDSolarwindsNode.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Remove-ITDSolarwindsNode.ps1" -Description "Remove-ITDSolarwindsNode.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "Infra-Monitoring-Solarwinds\Remove-ITDSolarwindsNode.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Get-ITDExpiredFiles.ps1" -Description "Get-ITDExpiredFiles.ps1" -Tag @('Team-Windows_Execute','ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.FileManagement\Get-ITDExpiredFiles.ps1" -Environment "PowerShell 7" -ErrorAction "Stop" -Credential "ndgov_svcitdpsuwin"
New-PSUScript -Name "test-sql.ps1" -Description "test-sql.ps1" -Path "ZM-Test\test-sql.ps1"
New-PSUScript -Name "New-ITDWindowsVmVMware_Step1.ps1" -Description "New-ITDWindowsVmVMware_Step1.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.Lifecycle\New-ITDWindowsVmVMware_Step1.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "New-ITDWindowsVmVMware_Step2.ps1" -Description "New-ITDWindowsVmVMware_Step2.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.Lifecycle\New-ITDWindowsVmVMware_Step2.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Add-ITDServerBuildRitmToSql.ps1" -Description "Add-ITDServerBuildRitmToSql.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.VirtualMachine\Add-ITDServerBuildRitmToSql.ps1" -Environment "Agent"
New-PSUScript -Name "Sync-ITDVMwareVMTagsFromCmdb.ps1" -Description "Sync-ITDVMwareVMTagsFromCmdb.ps1" -TimeOut "600" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.VirtualMachine\Sync-ITDVMwareVMTagsFromCmdb.ps1" -Environment "Agent" -Credential "ndgov_svcitdvmvcauto"
New-PSUScript -Name "New-ITDWindowsVm_Step3.ps1" -Description "New-ITDWindowsVm_Step3.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.Lifecycle\New-ITDWindowsVm_Step3.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "New-ITDWindowsVmAzure_Step1.ps1" -Description "New-ITDWindowsVmAzure_Step1.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.Lifecycle\New-ITDWindowsVmAzure_Step1.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "New-ITDWindowsVmAzure_Step2.ps1" -Description "New-ITDWindowsVmAzure_Step2.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.Lifecycle\New-ITDWindowsVmAzure_Step2.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "New-ITDWindowsVm_Auto.ps1" -Description "New-ITDWindowsVm_Auto.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.Lifecycle\New-ITDWindowsVm_Auto.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Get-HelloWorld.ps1" -Description "Get-HelloWorld.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ZM-Test\Get-HelloWorld.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Test-InvokeZM.ps1" -Description "Test-InvokeZM.ps1" -Path "ZM-Test\Test-InvokeZM.ps1"
New-PSUScript -Name "New-TestNestedInvoke.ps1" -Description "New-TestNestedInvoke.ps1" -Tag @('Team-Windows_Modify') -Path "ZM-Test\New-TestNestedInvoke.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Set-ITDVMwareVMTagFromCmdb.ps1" -Description "Set-ITDVMwareVMTagFromCmdb.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.VirtualMachine\Set-ITDVMwareVMTagFromCmdb.ps1" -Environment "Agent" -Credential "ndgov_svcitdvmvcauto"
New-PSUScript -Name "Move-ITDVMwareVMToAppNameFolder_Auto.ps1" -Description "Move-ITDVMwareVMToAppNameFolder_Auto.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.VirtualMachine\Move-ITDVMwareVMToAppNameFolder_Auto.ps1" -Environment "Agent" -Credential "ndgov_svcitdvmvcauto"
New-PSUScript -Name "Test-AzIaaSCredential.ps1" -Description "Test-AzIaaSCredential.ps1" -Path "ZM-Test\Test-AzIaaSCredential.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Remove-ITDExpiredFiles_Auto.ps1" -Description "Remove-ITDExpiredFiles_Auto.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "ITD-WindowsServer.FileManagement\Remove-ITDExpiredFiles_Auto.ps1" -Environment "PowerShell 7" -ErrorAction "Stop" -Credential "ndgov_svcitdpsuwin"
New-PSUScript -Name "Test-ZMFile.ps1" -Description "Test-ZMFile.ps1" -Tag @('Infra-VMware_Execute','Team-Windows_Execute') -Path "ZM-Test\Test-ZMFile.ps1"
New-PSUScript -Name "Update-ITDVMwareILOSslCertificate.ps1" -Description "Update-ITDVMwareILOSslCertificate.ps1" -TimeOut "300" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Administration\Update-ITDVMwareILOSslCertificate.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "Test-ZMVariable.ps1" -Description "Test-ZMVariable.ps1 [[-variable1] <string>] [[-variable2] <string>]" -Path "ZM-Test\Test-ZMVariable.ps1"
New-PSUScript -Name "Test-ITDScheduleWithCreds.ps1" -Description "Test-ITDScheduleWithCreds.ps1" -Path "ZM-Test\Test-ITDScheduleWithCreds.ps1" -Environment "Agent" -Credential "ndgov_svcitdiaasauto"
New-PSUScript -Name "New-ITDCertificateRequestSectigo.ps1" -Description "New-ITDCertificateRequestSectigo.ps1" -Tag @('Team-Windows_Execute','Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\New-ITDCertificateRequestSectigo.ps1" -Environment "PowerShell 7"
New-PSUScript -Name "Unregister-CommonName.ps1" -Description "Unregister-CommonName.ps1" -Tag @('Team-Windows_Execute','Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\Unregister-CommonName.ps1" -Environment "PowerShell 7"
New-PSUScript -Name "Invoke-CertAutoRenew.ps1" -Description "Invoke-CertAutoRenew.ps1" -Tag @('Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\Invoke-CertAutoRenew.ps1" -Environment "PowerShell 7"
New-PSUScript -Name "New-SectigoPfxCertificate.ps1" -Description "New-SectigoPfxCertificate.ps1" -Tag @('Team-Windows_Execute','Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\New-SectigoPfxCertificate.ps1" -Environment "PowerShell 7"
New-PSUScript -Name "Deploy-Client.ps1" -Description "Deploy-Client.ps1" -Tag @('ITD-WindowsServer_Modify') -Path "Infra-ActiveDirectory.Object\Deploy-Client.ps1"
New-PSUScript -Name "Troubleshooting.ps1" -Description "Troubleshooting.ps1" -Tag @('Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\Troubleshooting.ps1" -Environment "PowerShell 7"
New-PSUScript -Name "Register-CommonName.ps1" -Description "Register-CommonName.ps1" -TimeOut "60" -Tag @('Team-Windows_Execute','Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\Register-CommonName.ps1" -Environment "PowerShell 7"
New-PSUScript -Name "Update-Client.ps1" -Description "Update-Client.ps1" -Tag @('Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\Update-Client.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdpsuwin"
New-PSUScript -Name "Get-RegistrationList .ps1" -Description "Get-RegistrationList .ps1" -Tag @('Team-Windows_Execute','Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\Get-RegistrationList .ps1" -Environment "PowerShell 7"
New-PSUScript -Name "Invoke-CertificateDeploy.ps1" -Description "Invoke-CertificateDeploy.ps1" -Tag @('Infra-Certificate_Modify') -Path "Infra-Certificate-External.Sectigo\Invoke-CertificateDeploy.ps1" -Environment "PowerShell 7"
New-PSUScript -Name "Sync-ITDVMwareClusterMetadataToSql.ps1" -Description "Sync-ITDVMwareClusterMetadataToSql.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Administration\Sync-ITDVMwareClusterMetadataToSql.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdvmvcro"
New-PSUScript -Name "Sync-ITDVMwareHostMetadataToSql.ps1" -Description "Daily VMware Host metadata report for PowerBI trending and hardware capacity planning." -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Administration\Sync-ITDVMwareHostMetadataToSql.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdvmvcro"
New-PSUScript -Name "Sync-ITDVMwareVMMetadataToSql.ps1" -Description "Sync-ITDVMwareVMMetadataToSql.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Administration\Sync-ITDVMwareVMMetadataToSql.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdvmvcro"
New-PSUScript -Name "Sync-ITDOneViewServerInventoryToSql.ps1" -Description "Sync-ITDOneViewServerInventoryToSql.ps1" -Tag @('Infra-VMware_Modify') -Path "Infra-VMware.Administration\Sync-ITDOneViewServerInventoryToSql.ps1" -Environment "PowerShell 7" -Credential "ndgov_svcitdvmhpe"
@@ -0,0 +1,6 @@
$Parameters = @{
LogLevel = "Error"
HideRunAs = $true
HideRunOn = $true
}
Set-PSUSetting @Parameters
@@ -0,0 +1,21 @@
New-PSUTag -Name "Infra-VMware_Execute" -Color "#d4380d"
New-PSUTag -Name "Team-Windows_Execute" -Color "#391085"
New-PSUTag -Name "Team-Network_Execute" -Color "#c41d7f"
New-PSUTag -Name "Infra-VMware_Modify" -Color "#fa541c"
New-PSUTag -Name "Team-Windows_Modify" -Color "#722ed1"
New-PSUTag -Name "Team-Network_Modify" -Color "#f759ab"
New-PSUTag -Name "Team-Linux_Execute" -Color "#096dd9"
New-PSUTag -Name "Team-Linux_Modify" -Color "#40a9ff"
New-PSUTag -Name "Team-CND_Execute" -Color "#096dd9"
New-PSUTag -Name "Team-CND_Modify" -Color "#40a9ff"
New-PSUTag -Name "Team-Tier2_Execute" -Color "#389e0d"
New-PSUTag -Name "Team-Tier2_Modify" -Color "#7cb305"
New-PSUTag -Name "Shared-PowerSchool_Execute"
New-PSUTag -Name "Shared-PowerSchool_Modify"
New-PSUTag -Name "ITD-WindowsServer_Execute" -Color "#874d00"
New-PSUTag -Name "ITD-WindowsServer_Modify" -Color "#d48806"
New-PSUTag -Name "Team-Mgmt_Execute" -Color "#780650"
New-PSUTag -Name "Team-Mgmt_Modify" -Color "#c41d7f"
New-PSUTag -Name "Team-Collaboration_Execute" -Color "#ffe58f"
New-PSUTag -Name "Team-Collaboration_Modify" -Color "#ffd666"
New-PSUTag -Name "Infra-Certificate_Modify"
@@ -0,0 +1,16 @@
New-PSUVariable -Name "sql_itdpsu1" -Vault "Database" -Type "PSCredential"
New-PSUVariable -Name "ndgov_svcitdvmsnapmgr" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-VMware"
New-PSUVariable -Name "ndgov_svcitdvmvcauto" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-VMware" -Role @('App-Infra-VMware')
New-PSUVariable -Name "ndgov_svcitdpsuad" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-WindowsServer" -Role @('Team-Windows','Team-Tier2','App-Infra-VMware')
New-PSUVariable -Name "snow_vmcred" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-VMware"
New-PSUVariable -Name "ndgov_svcitdiaasauto" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-WindowsServer" -Role @('App-ITD-WindowsServer','Administrator')
New-PSUVariable -Name "ndgov_itdsccmsrvcpia" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-WindowsServer" -Role @('App-ITD-WindowsServer')
New-PSUVariable -Name "ndgov_svcitdpsuwin" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-WindowsServer" -Role @('App-ITD-WindowsServer','Team-Windows')
New-PSUVariable -Name "ndgov_svcitdvmvcro" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-VMware"
New-PSUVariable -Name "ndgov_svcitdiaassprw" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-VMware"
New-PSUVariable -Name "ndgov_itdvcenterscript" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-VMware" -Role @('App-Infra-VMware')
New-PSUVariable -Name "azure_iaasserviceprincipal" -Vault "Database" -Type "System.String" -Description "Owner: App-ITD-WindowsServer" -Role @('App-ITD-WindowsServer','Administrator')
New-PSUVariable -Name "SectigoClientSecret" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-Certificate-External"
New-PSUVariable -Name "ndgov_svcitdvmhpe" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-VMware" -Role @('App-Infra-VMware','Administrator')
New-PSUVariable -Name "sectigo_vmware" -Vault "Database" -Type "PSCredential" -Role @('App-Infra-VMware','Administrator')
New-PSUVariable -Name "pwdvault_WindowsCertificates" -Vault "Database" -Type "PSCredential" -Description "Owner: Infra-Certificate-External"
@@ -0,0 +1,13 @@
Param(
[string]
$ComputerName
)
If ($PSBoundParameters.ContainsKey('ComputerName')) {
$GetITDExpiredFilesParams = @{
ComputerName = $ComputerName;
}
Get-ITDExpiredFiles @GetITDExpiredFilesParams -Credential $Secret:ndgov_svcitdpsuwin -Verbose | Select-Object Name,DirectoryName,Extension,LastWriteTime,Length,PSComputerName | Format-Table -AutoSize
} Else {
Get-ITDExpiredFiles -Credential $Secret:ndgov_svcitdpsuwin -Verbose | Select-Object Name,DirectoryName,Extension,LastWriteTime,Length,PSComputerName | Format-Table -AutoSize
}
@@ -0,0 +1,119 @@
[CmdletBinding()]
param (
[string]
$ComputerName,
[switch]
$WhatIf
)
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$FilesRemovedSuccess = @()
$FilesRemovedFailure = @()
$GetITDExpiredFilesAutoParams += @{}
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "Infra_WindowsServer_FileManagement_RemoveITDExpiredFiles_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "Infra_WindowsServer_FileManagement_RemoveITDExpiredFiles_PRD"
}
}
If ($PSBoundParameters.ContainsKey('ComputerName')) {
Write-Verbose -Message "ComputerName parameter found" -Verbose
$GetITDExpiredFilesParams = @{
Credential = $Secret:ndgov_svcitdpsuwin
}
$GetITDExpiredFilesParams += @{
ComputerName = $ComputerName;
}
}
$FilesToRemove = Get-ITDExpiredFiles @GetITDExpiredFilesParams
Write-Verbose -Message ("Found " + $FilesToRemove.count + " expired files to remove") -Verbose
ForEach ($File in $FilesToRemove) {
Write-Verbose -Message ("Start~" + $File.PSComputerName + "~" + $File.FullName )
$ComputerName = $File.PSComputerName
$DateTime = Get-Date
$FullName = $File.FullName
$InvokeCommandParams = @{
ComputerName = $File.PSComputerName;
#Credential = $Secret:ndgov_svcitdpsuwin;
ErrorAction = 'Stop';
ArgumentList = @($File.FullName);
ScriptBlock = { Get-Item -Path $args[0] | Remove-Item }
}
switch ($WhatIf) {
$true {
Write-Verbose -Message "WhatIf switch true" -Verbose
try {
Write-Verbose -Message ("Process~" + $File.PSComputerName + "~" + $File.FullName + " removed")
Write-Host -Message ($Server.ComputerName + " -- " + 'What if: Performing the operation "Remove File" on target ' + $File.FullName)
# log success
$FilesRemovedSuccess += [PSCustomObject]@{
DateTime = $DateTime.tostring("yyyy/MM/dd HH:mm:ss");
ComputerName = $ComputerName;
FullName = $FullName;
}#>
Write-Output $File
}
catch {
Write-Verbose -Message ("Process~" + $File.PSComputerName + "~" + $File.FullName + " failure")
# log failure
$FilesRemovedFailure += [PSCustomObject]@{
DateTime = $DateTime.tostring("yyyy/MM/dd HH:mm:ss");
ComputerName = $ComputerName;
FullName = $FullName;
}
}
}
Default {
try {
Write-Verbose -Message "WhatIf switch default" -Verbose
Invoke-Command @InvokeCommandParams
Write-Verbose -Message ("Process~" + $File.PSComputerName + "~" + $File.FullName + " removed")
# log success to sql, add obj to array
$SqlQuery = "INSERT INTO [$Table] (PSUJobId, DateTime, ComputerName, Status, FullName) Values ('$PSUJobId', '$DateTime', '$ComputerName', 'Success', '$FullName')"
$SqlRecord = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
$FilesRemovedSuccess += [PSCustomObject]@{
DateTime = $DateTime.tostring("yyyy/MM/dd HH:mm:ss");
ComputerName = $ComputerName;
FullName = $FullName;
}
Write-Output $File
}
catch {
Write-Verbose -Message ("Start~" + $File.PSComputerName + "~" + $File.FullName + " failure")
# log failure to sql, add obj to array
$SqlQuery = "INSERT INTO [$Table] (PSUJobId, DateTime, ComputerName, Status, FullName) Values ('$PSUJobId', '$DateTime', '$ComputerName', 'Failure', '$FullName')"
$SqlRecord = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
$FilesRemovedFailure += [PSCustomObject]@{
DateTime = $DateTime.tostring("yyyy/MM/dd HH:mm:ss");
ComputerName = $ComputerName;
FullName = $FullName;
}
}
}
}
# create CHG request for the work
Write-Verbose -Message "Submit CHG for the work. TBD" -Verbose
Write-Verbose -Message ("End~" + $File.PSComputerName + "~" + $File.FullName ) -Verbose
### Generate CHG
}
@@ -0,0 +1,146 @@
# cron expression
# 47 8-16 * * 1-5
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 | 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) {
$Ci = $null
$BuildComplete = $null
# get SCTask, Ritm
$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]
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)
}
$ComputerName = ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).host_name
$OperatingSystem = ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).operating_system
switch ( ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).target_platform ) {
'azure' { $target_platform = "Azure" }
'vmware' { $target_platform = "VMware" }
}
$FormFQDN = ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).host_name
$FormHostName = $FormFQDN.split('.')[0]
$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 agents are running"
$ProcessList = @('ccmexec', 'cohesity*', 'nessus*', 'cortex*')
switch ($target_platform) {
'VMware' {
$ProcessList += 'vmtoolsd'
}
'Azure' {
Write-Verbose -Message "vmtoolsd not required for Azure VM"
}
Default {
Write-Verbose -Message "no Ci means no platform check"
}
}
}
catch {
Write-Error $error[0]
}
If ( $ComputerName -like "*.nd.gov" ) {
try {
$AgentCount = 0
$svcitdpsuwin = Get-ITDPassword -UserName ndgov\svcitdpsuwin -Title ndgov\svcitdpsuwin
$RunningProcess = Invoke-Command -Credential $svcitdpsuwin -ComputerName $FormFQDN -ArgumentList $ProcessList -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 "$FormFQDN unreachable via PSRemoting"
$BuildComplete = $false
}
} Else {
Write-Verbose -Message ($SCTaskNum + $ComputerName + " is not nd.gov, manual agent validation required.") -Verbose
}
<# if Task has been open for more than x hours, update description for humans to review
$Hours = 6
If ($SCTask.opened_at.value -lt (Get-Date).AddHours(-$Hours)) {
$work_notes = ("New build Ci has not been found after $Hours hours, problem may have occurred. Please review.`nPSU Job Id #" + $UAJob.Id)
$shortdescription = "$target_platform $OperatingSystem VM Build for $ComputerName, NEED HUMAN REVIEW"
<#Update-ServiceNowRecord -ID $SCTask.number -Values @{
work_notes = $work_notes;
shortdescription = $shortdescription;
}
}#>
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 $FormFQDN Windows Guest OS complete. `nPSU Job Id #" + $UAJob.Id)
$shortdescription = "$target_platform $hardware_type $FormFQDN 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,130 @@
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTask')]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$ComputerName,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[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;
CPU = $CPU;
MemoryGB = $MemoryGB;
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-ITDWindowsVmAzure @NewITDWindowsVmAzureParams -Credential $Secret:ndgov_svcitdiaasauto -Verbose
@@ -0,0 +1,118 @@
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'FromSCTask')]
$SCTaskNum,
[Parameter(Mandatory = $true, ParameterSetName = 'ManualEntry')]
[string]
$ComputerName,
[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]
$Environment = '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 = @{
ComputerName = $ComputerName;
CPU = $CPU;
MemoryGB = $MemoryGB;
DiskOsGB = $DiskOsGB;
DiskSwapGB = $DiskSwapGB;
DiskDataGB = $DiskDataGB;
Subnet = $Subnet;
OS = $OS;
Environment = $Environment;
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' }
}
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 = @{
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 );
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 );
Environment = ( $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-Host $NewITDWindowsVmVMwareParams
New-ITDWindowsVmVMware @NewITDWindowsVmVMwareParams -Credential $Secret:ndgov_svcitdiaasauto -Verbose
Write-Warning -Message "New-ITDWindowsVmVMware function completed"
Write-Verbose -Message "Disconnect from vCenter" -Verbose
Disconnect-ITDvCenter
@@ -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
@@ -0,0 +1,96 @@
<#
.SYNOPSIS
Add Service Principal Name to a ITD AD Service Account
.DESCRIPTION
Add Service Principal Name to a ITD AD Service Account
.NOTES
example using setspn:
setspn.exe -s MSSQLSvc/test.nd.gov:1433 ndgov\svctest
setspn.exe -s MSSQLSvc/test:1433 ndgov\svctest
setspn.exe -s MSSQLSvc/test.nd.gov ndgov\svctest
setspn.exe -s MSSQLSvc/test ndgov\svctest
setspn.exe -s MSSQLSvc/test.nd.gov ndgov\svctest
.LINK
#>
[CmdletBinding()]
Param(
[string]
$SamAccountName,
[Parameter(HelpMessage = "Multiple entries can be submitted if the field loses focus, and you go back to it. For example, after each entry hit Tab, then Shift-Tab back.")]
[string[]]
$ServicePrincipalName = $null
)
Write-Verbose -Message "Prep Variables and Connections"
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" {
$ServiceNowEnvironment = 'Test'
}
"ITDWINAUTOP1" {
$ServiceNowEnvironment = 'Production'
}
}
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$StartDateTime = Get-Date
Write-Verbose -Message "Find AD User" -Verbose
$ADUser = Get-ADUser -Identity $SamAccountName -ErrorAction Stop
Write-Verbose -Message "Add SPN(s)" -Verbose
try {
$ServicePrincipalName | ForEach-Object {
Write-Verbose -Message ("Attempt to add SPN value " + $_) -Verbose
$ADUser | Set-ADUser -ServicePrincipalNames @{Add=$_}
}
}
catch {
Write-Error $Error[0]
}
Start-Sleep -Seconds 2
Write-Verbose -Message "No errors when adding the SPNs, listing the SPNs here for human validation" -Verbose
$ValidateUser = Get-ADUser -Identity $SamAccountName -Properties ServicePrincipalNames | Select-Object SamAccountName, ServicePrincipalNames
$ValidateUser.ServicePrincipalNames
Write-Verbose -Message "Generate ServiceNow CHG" -Verbose
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred -Verbose
$NewITDServiceNowChangeRequestParams = @{
TemplateName = 'NDIT-SPS-Server Add/Chg/Del'
RequestedByUsername = $RequestedBy.split('@')[0] -replace 'prv';
Category = 'Systems Platforms - Systems';
Subcategory = 'Windows';
Impact = 3;
ShortDescription = "ServicePrincipalName added to ndgov\$SamAccountName - PSU Job Id $PSUJobId";
Description = "ServicePrincipalName added to ndgov\$SamAccountName - PSU Job Id $PSUJobId, see notes for details";
Justification = "ServicePrincipalName is required to be added to Active Directory Service Accounts by some applications";
Implementation = "PSUniversal execution";
RiskImpactAnalysis = "Low";
BackoutPlan = "Remove the new service principal name from the serviceprincipalname attribute."
TestPlan = "n/a"
WhoIsImpacted = "Windows System Administrators";
StartTime = $StartDateTime
EndTime = $StartDateTime.AddMinutes(1);
AssignmentGroup = 'NDIT-Computer Systems Windows';
ChangeManagerUsername = 'khellman';
ChangeCoordinatorUsername = 'gpgolberg';
AssignedToUsername = $RequestedBy.split('@')[0] -replace 'prv';
}
$CHG = New-ITDServiceNowChangeRequest @NewITDServiceNowChangeRequestParams -Verbose
$CHGNum = $CHG.Number.value
Write-Verbose -Message ("Completing SNow " + $CHG.Number.value) -Verbose
$CompleteITDServiceNowChangeRequestParams = @{
Number = $CHG.Number.value
CloseCode = "Successful"
CloseNotes = "ServicePrincipalNames added to ndgov\$SamAccountName - PSU Job Id $PSUJobId`n" + ($ServicePrincipalName | ForEach-Object {$_})
}
Complete-ITDServiceNowChangeRequest @CompleteITDServiceNowChangeRequestParams -Verbose
@@ -0,0 +1 @@
# It all starts with a single line of powershell code.
@@ -0,0 +1,134 @@
<#
.SYNOPSIS
Creates an Active Directory user/service account for the nd.gov domain
.DESCRIPTION
Creates an Active Directory user/service account for the nd.gov domain.
.NOTES
The PasswordstateList parameter must be validated. If a Passwordstate Password List to the options, ensure that the ndgov\svcitdiaasauto Active Directory has modify access on the Password List.
Requires Integrated or Agent environment. If not chosen, an erroneous error is caused during the invocation of New-ITDADServiceAccount when the PSCredential object is created to be returned to the user, see below.
[error] Exception calling ".ctor" with "2" argument(s): "Cannot process argument because the value of argument "password" is null. Change the value of argument "password" to a non-null value."
The agent environment is selected to reduce parameter during script execution, and Run As Credential is enforced as svcitdpsuwin
.LINK
https://northdakota.service-now.com/kb_view.do?sysparm_article=KB0016867
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true,
HelpMessage = "Only nd.gov domain is supported at this time.")]
[ValidateSet("nd.gov")]
[string]
$DomainName = 'nd.gov',
[Parameter(Mandatory = $true,
HelpMessage = "This is the account name. This value will also be set on the Active Directory Surname attribute (GivenName or Surname are required for ServiceNow lookups)")]
[string]
$SamAccountName,
[Parameter(Mandatory = $true,
HelpMessage = "Will be set on the respective Passwordstate record property and Active Directory attribute. '1120' will automatically be appended to the entry.")]
[string]
$Description,
[Parameter(Mandatory = $true,
HelpMessage = "What goes into the Passwordstate record Title field. Generally a FQDN for the server that will use this service account.")]
[string]
$PasswordstateTitle,
[Parameter(Mandatory = $true,
HelpMessage = "The Passwordstate Password List where the credentials to be saved. Go here to retrieve the password for the new account.")]
[ValidateSet('CSRC', 'VMware_Systems','Peoplesoft Share PW')]
[string]
$PasswordstateList
)
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$StartDateTime = (Get-Date)
$EndDateTime = $StartDateTime.AddMinutes(1)
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch ($UAJob.ComputerName) {
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_ActiveDirectory_Object_NewITDADServiceAccount_NPD"
$ServiceNowEnvironment = 'Test'
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_ActiveDirectory_Object_NewITDADServiceAccount_PRD"
$ServiceNowEnvironment = 'Production'
}
}
Write-Verbose -Message "fix samaccountname" -Verbose
$SamAccountName = $SamAccountName.Tolower()
# add to SQL
Write-Verbose -Message "Add request to SQL" -Verbose
$SqlQuery = "INSERT INTO [$SnapshotTable] (PSUJobId,RequestedBy,DateTime,Status,DomainName,SamAccountName,Description,PasswordstateTitle,PasswordstateList) Values ('$PSUJobId', '$RequestedBy', '$StartDateTime','Requested','$DomainName','$SamAccountName', '$Description', '$PasswordstateTitle', '$PasswordstateList');"
Write-Verbose -Message $SqlQuery -Verbose
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
# Do the work
Write-Verbose -Message "Create the account in Active Directory, and Passwordstate record" -Verbose
New-ITDADServiceAccount -SamAccountName $SamAccountName -Description $Description -PasswordstateList $PasswordstateList -PasswordstateTitle $PasswordstateTitle -Credential $Secret:ndgov_svcitdpsuad -Verbose
Write-Verbose -Message "Executing Get-ADUser -Identity $SamAccountName" -Verbose
# Validate the user
$ADUser = Get-ADUser -Identity $SamAccountName
If ($ADUser) {
Write-Output $ADUser
Write-Verbose -Message "Create CHG request for the work" -Verbose
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$NewITDServiceNowChangeRequestParams = @{
TemplateName = 'NDIT-SPS-Server Add/Chg/Del'
RequestedByUsername = $RequestedBy.split('@')[0] -replace 'prv';
Category = 'Systems Platforms - Systems';
Subcategory = 'Windows';
Impact = 3;
ShortDescription = "New $DomainName Active Directory service account $SamAccountName created - PSU Job Id $PSUJobId";
Description = "New $DomainName Active Directory service account $SamAccountName created";
Justification = "New $DomainName Active Directory service account required for zero-trust policies, following guidelines found in KB0016867";
Implementation = "PSUniversal execution";
RiskImpactAnalysis = "Low";
BackoutPlan = "Delete the new user account"
TestPlan = "n/a"
WhoIsImpacted = "Windows System Administrators";
StartTime = $StartDateTime
EndTime = $StartDateTime.AddMinutes(1);
AssignmentGroup = 'NDIT-Computer Systems Windows';
ChangeManagerUsername = 'khellman';
ChangeCoordinatorUsername = 'gpgolberg';
AssignedToUsername = $RequestedBy.split('@')[0] -replace 'prv';
}
$CHG = New-ITDServiceNowChangeRequest @NewITDServiceNowChangeRequestParams -Verbose
$CHGNum = $CHG.Number.value
Write-Verbose -Message ("Completing SNow " + $CHG.Number.value) -Verbose
$CompleteITDServiceNowChangeRequestParams = @{
Number = $CHG.Number.value
CloseCode = "Successful"
CloseNotes = ("New $DomainName Active Directory account " + $obj.ADDomain + "\" + $obj.SamAccountName + " created.")
}
Complete-ITDServiceNowChangeRequest @CompleteITDServiceNowChangeRequestParams -Verbose
Write-Verbose -Message "Status Success" -Verbose
$SQLStatus = "Succcess"
}
Else {
Write-Verbose -Message "Status Failure" -Verbose
$SQLStatus = "Failure"
}
#>
Write-Verbose -Message "Update SQL with that CHG num and update Status" -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = '$SQLStatus', SNowCHGNum = '$CHGNum' WHERE PSUJobId = " + $PSUJobId)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
@@ -0,0 +1,3 @@
Import-Module ITD.Infra-Certificate-External.JsonDB
SET-JDEnvironment -Name prod
select-JDJson -TableName certcache|select CommonName,is_retired,ExpiryDate
@@ -0,0 +1,60 @@
# It all starts with a single line of powershell code.
"I ran at: " + (get-date)
$ENV:USERNAME
Write-Verbose -Verbose "Import Modules"
#Remove-Module ITD.Infra-Certificate-External.JsonDB
Import-Module ITD.Infra-Certificate-External.JsonDB
Import-Module ITD.Infra-Certificate-External.General -DisableNameChecking
Write-Verbose -Verbose "Setting Database Environment"
Set-JDEnvironment -Name Prod
Write-Verbose -Verbose "Collect certs up for Renewal"
$certs=Get-ICE-CertUpforRenewal
Write-Verbose -Verbose "Proccessing Certs"
foreach ($cert in $certs) {
"Processing: " + $cert.CommonName
Write-Host $cert.CommonName
Write-Host $cert.ParameterSetName
if ($cert.ParameterSetName -eq "Cloud Service") {
$AppParams = @{
CommonName = $cert.CommonName
SubjectAlternative = $cert.SubjectAlternative
ApplicationName = $cert.ApplicationName
}
}
elseif ($cert.ParameterSetName -eq "Windows") {
$AppParams = @{
CommonName = $cert.CommonName
SubjectAlternative = $cert.SubjectAlternative
DestinationServer = $cert.DestinationServer
PfxtoPasswordState = ([System.Convert]::ToBoolean($cert.PfxtoPasswordState))
}
}
else {
"Param set not defined: " + $cert.CommonName
}
# Define the script you want to run
$ScriptName = "Infra-Certificate-External.Sectigo/New-SectigoPfxCertificate.ps1"
# Invoke the script and store the job object
$Job = Invoke-PSUScript -Name $ScriptName -Integrated -Parameters $AppParams
}
#exit
$job
@@ -0,0 +1,61 @@
#Param (
# $DestinationServer,
# [string]$Email
#)
$PSUJobId = $UAJob.Id
Set-JDEnvironment -Name Prod
$MaintenanceWindow=(Get-ICE-MaintenanceWindow -Credential $Secret:snow_vmcred)
if ($MaintenanceWindow.ScheduledThisMonth -eq $false) {
Send-ICE-Mail -jobid $PSUJobId -Message "Maintence Window Failed Integraty Check" -Status ActionNeeded -recipientsString fjpeterson@nd.gov
}
$Day=$MaintenanceWindow
$Day=$MaintenanceWindow.DaysToChangeWindow
"It is $Day days to Production Maintenance Window."
if ($MaintenanceWindow.DaysToChangeWindow -eq 10 -and $Hour -eq "18") { #6pm Thursday
$Message="Deploying Cert Changes to Test"
Send-ICE-Mail -jobid $PSUJobId -message $Message -recipientsString fjpeterson@nd.gov
#Idealy we get the oneds that were applied this week have to use date of not before Feild!
$DestinationServer=(Get-ICE-CertUpforDeploy|Where-Object {$_.Environment -eq "Test"}).DestinationServer
} elseif ($MaintenanceWindow.DaysToChangeWindow -eq 0 -and $Hour -eq "4") { #4am Sunday
$Message="Deploying Cert Changes to Production"
Send-ICE-Mail -jobid $PSUJobId -message $Message -recipientsString fjpeterson@nd.gov
$DestinationServer=(Get-ICE-CertUpforDeploy|Where-Object {$_.Environment -eq "Production"}).DestinationServer
$DestinationServer=$null #Disable prod for now!
} else {
"Skipping - Not time for Production or Test Maintenance"
}
$Scriptblock = {
$config="C:\ProgramData\ITD\ITD.Infra-Certificate-External.Client\Config\IISBindingConfig.json"
if (Test-Path $config) {
Update-CCIISCertificateBinding 6>$null 2>&1
$Configured=$true
}
$config2="C:\ProgramData\ITD\ITD.Infra-Certificate-External.Client\Config\IISBindingConfig2.json"
if (Test-Path $config2) {
Invoke-CCIISCertificateUpdateFromConfig 6>$null 2>&1
$Configured=$true
}
If (!$Configured) {
$hn=(hostname)
"Skipped $hn - Not Configured"
}
}
ForEach ($ComputerName in $DestinationServer ) {
$results=Invoke-Command -ComputerName $ComputerName -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock $Scriptblock
if ($results -eq $null) {
Send-ICE-Mail -jobid $PSUJobId -message "$ComputerName Binding Not Configured, Will not update website" -recipientsString fjpeterson@nd.gov
}
}
@@ -0,0 +1,489 @@
<#
.SYNOPSIS
Sectigo Certificate Creator
.DESCRIPTION
Creates a Sectigo Certificate for ITD Organization
.NOTES
Requires:
ITD.Infra-Certificate-Internal.Sectigo
.LINK
https://northdakota.service-now.com/kb_view.do?sysparm_article=KB0018128
#>
[CmdletBinding()]
param (
# [Parameter(Mandatory = $true,
# HelpMessage = "CRC TEXT ONLY")]
# [string]
# $CSR,
# [Parameter(Mandatory = $true,
# HelpMessage = "Csr File")]
# [file]
# $CSRfile,
# [Parameter(Mandatory = $true,
# HelpMessage = "Server Type")]
# [ValidateSet('IIS','IIS_OLD','IBM','LINUX','Apache','Tomcat')]
#[string]
#$ServerType="IIS",
[Parameter(Mandatory = $true,
HelpMessage = "Email address for notifications, comma seperated")]
[string]
$RequesterEmail,
[Parameter(Mandatory = $true,
HelpMessage = "Common Name for cert")]
[string]
$CommonName,
[Parameter(Mandatory = $true,
HelpMessage = "Comma separated.")]
[string]
$SubjectAlternative,
[Parameter(Mandatory = $true,
HelpMessage = "Host for Cert Delivery")]
[string]
$DestinationServer
#[Parameter(Mandatory = $true,
#HelpMessage = "Key Type for cert")]
#[string]
#[ValidateSet("RSA")]
#[Parameter(HelpMessage = "Optional Field, will be appended to standard comments")]
#[string]
#$Comments
#[Parameter(Mandatory = $true,
# HelpMessage = "File Format")]
#[ValidateSet('x509','x509CO','base64','bin','x509IOR','pem','pemco','pemia','x509R')]
#[string]
#$Format="pem"
)
#PSU Reassignment per Zacks standards
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$KeyType="RSA" #reminder this would need to be set on csr.
#Load Updated Modules
#Find-Module -Repository ITD_PwshGallery -Name ITD.Infra-Certificate-Internal.Sectigo | Update-Module
#exit
#Map script vars to ones that can be Changed for Display Only
$subjAltNames=$SubjectAlternative
$dsvEmail = $RequesterEmail
$myhost=$DestinationServer
#Set ad Default to Hide from End user.
$ServerType="IIS"
$Format="x509CO"
#Write-Verbose -Message $Secret:ndgov_svcitdpsuwin.username -Verbose
#Testing Service Now module
#Get-Command Get-ServiceNowRecord
#Block access while testing
#if ($RequestedBy -ne 'prvfjpeterson@nd.gov' -and $RequestedBy -ne 'prvnblowers@nd.gov' )
#{
# Write-Error "Check with freeman script is currenly disabled"
# exit
#}
if ($Csrfile){
$csr= [Text.Encoding]::UTF8.GetString($CSRfile.Content)
}
Write-Verbose -Message "Validate Email Address" -Verbose
$EmailAddressList = $dsvEmail -split ","
foreach ($e in $EmailAddressList) {
$user = Get-ADUser -Filter "Mail -eq '$e'" -Properties Mail
$group=Get-ADGroup -Filter "Mail -eq '$($e)'" -Properties Mail
if ($user -or $group) {
Write-Verbose -Message "$e Passed testing" -Verbose
}
else {
Write-Error "$e is an invalid email address. Terminating Script"
exit
}
}
Write-Verbose -Message "Validate host" -Verbose
$remotehi=Invoke-Command -ComputerName $myhost -ScriptBlock {"hi"} -Credential $Secret:ndgov_svcitdpsuwin
if ($remotehi -eq "hi") {
"Connection to host Succeded"
} else {
"Connection to host failed"
exit
}
Write-Verbose -Message "Retrieve CI from ServiceNow" -Verbose
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$IP=(Resolve-DnsName -Name $DestinationServer).IPAddress
$Filter= "ip_address=$ip^operational_status=1"
$Fields=("FQDN","ip_address","Location","model_id","Name","dns_domain","os_domain","Schedule","Environment","sys_class_name","u_nd_application_svc","discovery_source","support_group")
$CI= Get-ITDServiceNowRecord -Table "cmdb_ci_win_server" -Filter $Filter -Fields $Fields -First 1
$ApplicationName=$CI.u_nd_application_svc.display_value
if (!$ApplicationName) {
write-Error "CI NOT FOUND"
exit
}
$customFields = @(
[pscustomobject]@{ name = "ApplicationName"; value = $ApplicationName }
)
#done validation
#
# Do the work
#
#>
## Cert REquest
Write-Verbose -Message "Create CSR" -Verbose
$csrScriptBlock={
param ($commonName)
#######################
# Setting the variables
#######################
$UID = [guid]::NewGuid()
$files = @{}
$files['settings'] = "$($env:TEMP)\$($UID)-settings.inf";
$files['csr'] = "$($env:TEMP)\$($UID)-csr.req"
$request = @{}
$request['SAN'] = @{}
Write-Host "Provide the Subject details required for the Certificate Signing Request" -ForegroundColor Yellow
$request['CN'] = $commonName
$request['O'] = "NDIT"
$request['OU'] = "State Of North Dakota"
$request['L'] = "Bismarck"
$request['S'] = "ND"
$request['C'] = "US"
#########################
# Create the settings.inf
#########################
$settingsInf = "
[Version]
Signature=`"`$Windows NT`$
[NewRequest]
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
RequestType = PKCS10
ProviderName = `"Microsoft RSA SChannel Cryptographic Provider`"
ProviderType = 12
HashAlgorithm = sha256
;Variables
Subject = `"CN={{CN}},OU={{OU}},O={{O}},L={{L}},S={{S}},C={{C}}`"
[Extensions]
{{SAN}}
;Certreq info
;http://technet.microsoft.com/en-us/library/dn296456.aspx
;CSR Decoder
;https://certlogik.com/decoder/
;https://ssltools.websecurity.symantec.com/checker/views/csrCheck.jsp
"
$request['SAN_string'] = & {
if ($request['SAN'].Count -gt 0) {
$san = "2.5.29.17 = `"{text}`"
"
Foreach ($sanItem In $request['SAN'].Values) {
$san += "_continue_ = `"dns="+$sanItem+"&`"
"
}
return $san
}
}
$settingsInf = $settingsInf.Replace("{{CN}}",$request['CN']).Replace("{{O}}",$request['O']).Replace("{{OU}}",$request['OU']).Replace("{{L}}",$request['L']).Replace("{{S}}",$request['S']).Replace("{{C}}",$request['C']).Replace("{{SAN}}",$request['SAN_string'])
# Save settings to file in temp
$settingsInf > $files['settings']
# Done, we can start with the CSR
#Clear-Host
#################################
# CSR TIME
#################################
# Display summary
Write-Host "Certificate information
Common name: $($request['CN'])
Organisation: $($request['O'])
Organisational unit: $($request['OU'])
City: $($request['L'])
State: $($request['S'])
Country: $($request['C'])
Subject alternative name(s): $($request['SAN'].Values -join ", ")
Signature algorithm: SHA256
Key algorithm: RSA
Key size: 2048
" -ForegroundColor Yellow
certreq -new $files['settings'] $files['csr'] > $null
# Output the CSR
$CSR = Get-Content $files['csr']
$CSR|Out-String
} #end of script block
#myhost is used as cn
$csr=Invoke-Command -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock $csrScriptBlock -ArgumentList $commonName
#Write-Verbose -Message "Validate CSR" -Verbose
#$TestResults=Test-SectigoCertificateRequest -csr $csr
#If ($TestResults.Valid -eq $True) {
# Write-Verbose -Message "CSR Passed Testing" -Verbose
#}
#else {
# Write-Error "You don't have a valid csr. Terminating Script"
# "CSR Content " + $csr
# exit
#}
# End of Creating csr
##
$Comments="Enrolled by PSUniversal, Job " + $UAJob.Id + ", User " + $UAJob.Identity.Name + "," + $Comments
$Comments
if ($ApplicationName)
{
$customFields = @(
@{
name = "ApplicationName"
value = $ApplicationName
}
)
}
Write-Verbose -Message "Setting up params for Enroll-SectigoCertificateRequest" -Verbose
$splat = @{
Csr=$csr
dcvEmail=$dsvEmail
Comment=$Comments
KeyType=$KeyType
subjAltNames=$subjAltNames
}
$b1 = @{
customFields = $customFields
}
if ($customFields) {
$splat = $splat+ $b1
}
#$splat2=@{
# subjAltName=$subjAltName
#}
#if ( $subjAltName) {
# $Splat = $splat + $splat2
#}
$cred=$Secret:SectigoClientSecret
$env:Sectigoclientid = $cred.UserName
$env:SectigoclientSecret = $cred.GetNetworkCredential().Password
#get-command -Module ITD.Infra-Certificate-Internal.Sectigo
#remove-module ITD.Infra-Certificate-Internal.Sectigo
Write-Verbose -Message "Enroll-SectigoCertificateRequest" -Verbose
Get-SectigoApiToken
$certRequest = Enroll-SectigoCertificateRequest @Splat
#seems to be issue with this requiring addtional wait time.
Write-Verbose -Message "Waiting for Cert Status" -Verbose
while ($certstatus -ne "Issued") {
$certstatus=(Get-SectigoCertificate -OrderId $certRequest.sslid).status
Sleep 1
$run= $run + 1
if ($run -gt 60) {
Write-Error "Failed to get issue status after 1 minute..exiting"
exit
}
}
$tp=(Get-SectigoCertificate -OrderId $certRequest.sslid).sha1Hash
"tp: $tp"
Write-Verbose -Message "Downloading interm Certificate" -Verbose
$IntermCertRootPath="c:\psautocerts_interm\"
mkdir $IntermCertRootPath 2>$null
$IntermCertPath = (Download-SectigoCertificate -Orderid $certRequest.sslid -Format x509IOR -CertRootPath $IntermCertRootPath).FullName
ls $IntermCertPath |select FullName, LastWriteTime, Length
Write-Verbose -Message "Downloading Certificate" -Verbose
$CertRootPath="c:\psautocerts\"
mkdir $CertRootPath 2>$null
$CertPath = (Download-SectigoCertificate -Orderid $certRequest.sslid -Format $Format -CertRootPath $CertRootPath).FullName
ls $CertPath |select FullName, LastWriteTime, Length
# Define source and destination paths
$remoteCertPath = "C:\Temp\CertificateX.cer" # A temporary location on the remote machine
$IntermremoteCertPath = "C:\Temp\Interm_CertificateX.cer"
# Copy the interm certificate file to the remote machine
Copy-Item -Path $IntermCertPath -Destination $IntermremoteCertPath -ToSession (New-PSSession -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin)
# Copy the certificate file to the remote machine
Copy-Item -Path $CertPath -Destination $remoteCertPath -ToSession (New-PSSession -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin)
# Define parameters for importing the certificate
#$certPassword = "YourCertPassword" | ConvertTo-SecureString -AsPlainText -Force # If it's a PFX with a password
$IntermcertStoreLocation = "Cert:\LocalMachine\Root"
$Intermcertimport=Invoke-Command -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock {
param($IntermremoteCertPath, $IntermcertStoreLocation )
"Import-Certificate -FilePath -CertStoreLocation $IntermcertStoreLocation"
Import-Certificate -FilePath $IntermremoteCertPath -CertStoreLocation $IntermcertStoreLocation
if (Test-Path -Path $IntermremoteCertPath -PathType Leaf) {
Remove-Item -Path $IntermremoteCertPath -Force -Confirm:$false 2>$null
}
# Import the certificate
} -ArgumentList $IntermremoteCertPath, $IntermcertStoreLocation
if ($Intermcertimport.Thumbprint ) {
Write-Verbose -verbose "Successful Import."
$IntermThumbprint=$Intermcertimport.Thumbprint
Write-Verbose "Thumbprint: $IntermThumbprint"
if (Test-Path -Path $CertPath -PathType Leaf) {
Remove-Item -Path $IntermCertPath -Force -Confirm:$false
Write-Host "File '$IntermCertPath' deleted successfully."
} else {
Write-Host "Path '$IntermCertPath' does not exist or is not a file."
}
}
##################
$certStoreLocation = "Cert:\LocalMachine\My"
$certimport=Invoke-Command -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock {
param($remoteCertPath, $certStoreLocation,$CommonName )
"Import-Certificate -FilePath $remoteCertPath -CertStoreLocation $certStoreLocation"
# Import the certificate
$cert=Import-Certificate -FilePath $remoteCertPath -CertStoreLocation $certStoreLocation
$mydate=Get-Date -Format 'yyyy-MM-dd'|out-string
$FriendlyName = $CommonName + "-" +$myDate
$cert.FriendlyName = $FriendlyName
if (Test-Path -Path $remoteCertPath -PathType Leaf) {
Remove-Item -Path $remoteCertPath -Force -Confirm:$false 2>$null
}
$cert
} -ArgumentList $remoteCertPath, $certStoreLocation,$CommonName
if ($certimport.Thumbprint ) {
Write-Verbose -verbose "Successful Import."
$Thumbprint=$certimport.Thumbprint
Write-Verbose "Thumbprint: $Thumbprint" -Verbose
if (Test-Path -Path $CertPath -PathType Leaf) {
Remove-Item -Path $CertPath -Force -Confirm:$false
Write-Host "File '$CertPath' deleted successfully."
} else {
Write-Host "Path '$CertPath' does not exist or is not a file."
}
}
#
# Request Work
#
# Validate the user
$StartDateTime = (Get-Date)
$EndDateTime = $StartDateTime.AddMinutes(1)
$RequestedBy=$UAJob.Identity.Name
#$ServiceNowEnvironment = "TEST"
#TemplateName = 'NDIT-SPS-Ansible Automation Platform'
if ($certimport.Thumbprint ) {
Write-Verbose -Message "Create CHG request for the work" -Verbose
$ServiceNowEnvironment = "Production" #'Production', 'Test', 'Development'
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$NewITDServiceNowChangeRequestParams = @{
TemplateName = 'NDIT-SPS-PSU Cert Automation Platform'
RequestedByUsername = $RequestedBy.split('@')[0] -replace 'prv';
Category = 'Systems Platforms - Systems';
Subcategory = 'Windows';
Impact = 3;
ShortDescription = "New Certificate Created - PSU Job Id $PSUJobId";
Description = "New Certificate Created - PSU Job Id $PSUJobId";
Justification = "Security Standards require an updated certificate";
Implementation = "PSUniversal execution";
RiskImpactAnalysis = "Low";
BackoutPlan = "Revoke Cert"
TestPlan = "n/a"
WhoIsImpacted = "Windows System Administrators";
StartTime = $StartDateTime
EndTime = $StartDateTime.AddMinutes(1);
AssignmentGroup = 'NDIT-Computer Systems Windows';
ChangeManagerUsername = 'khellman';
ChangeCoordinatorUsername = 'gpgolberg';
AssignedToUsername = $RequestedBy.split('@')[0] -replace 'prv';
}
$CHG = New-ITDServiceNowChangeRequest @NewITDServiceNowChangeRequestParams -Verbose
$CHGNum = $CHG.Number.value
Write-Verbose -Message ("Completing Snow " + $CHG.Number.value) -Verbose
$CompleteITDServiceNowChangeRequestParams = @{
Number = $CHG.Number.value
CloseCode = "Successful"
CloseNotes = ("New Certificate" + $obj.ADDomain + "\" + $obj.SamAccountName + " created.")
}
Complete-ITDServiceNowChangeRequest @CompleteITDServiceNowChangeRequestParams -Verbose
Write-Verbose -Message "Status Success" -Verbose
$SQLStatus = "Succcess"
}
Else {
Write-Verbose -Message "Status Failure" -Verbose
$SQLStatus = "Failure"
}
@@ -0,0 +1,426 @@
<#
.SYNOPSIS
Sectigo Certificate Creator
.DESCRIPTION
Creates a Sectigo Certificate for ITD Organization
.NOTES
Requires:
ITD.Infra-Certificate-Internal.Sectigo
.LINK
https://northdakota.service-now.com/kb_view.do?sysparm_article=KB0018128
#>
[CmdletBinding(DefaultParameterSetName = 'Windows')]
param(
# Email address for notifications, comma seperated
# [Parameter(Mandatory, ParameterSetName = 'Windows')]
# [Parameter(Mandatory, ParameterSetName = 'Cloud Service')]
# [String]$RequesterEmail,
# Common Name for cert
[Parameter(Mandatory, ParameterSetName = 'Windows')]
[Parameter(Mandatory, ParameterSetName = 'Cloud Service')]
[String]$CommonName,
# Comma separated.
[Parameter(Mandatory, ParameterSetName = 'Windows')]
[Parameter(Mandatory, ParameterSetName = 'Cloud Service')]
[String]$SubjectAlternative,
# Host for Cert Delivery, comma seperated
[Parameter(Mandatory, ParameterSetName = 'Windows')]
[String]$DestinationServer,
# Option for pfx in PasswordState
[Parameter(Mandatory, ParameterSetName = 'Windows')]
[bool]$PfxtoPasswordState,
# AppName CI in CMDB
[Parameter(Mandatory, ParameterSetName = 'Cloud Service')]
[String]$ApplicationName
)
process {
#Find-Module -Repository ITD_PwshGallery -Name ITD.Infra-Certificate-External.General|Update-Module -Scope CurrentUser
#exit
Import-Module ITD.Infra-Certificate-External.General -DisableNameChecking
Import-Module ITD.Infra-Certificate-External.JsonDB
#We reusing and breaking it up to an array for further use in script
$DestinationServerArray = $DestinationServer -split ","
#PSU Reassignment per Zacks standards
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
#$Test Mode
# - Blocks Access to selected users
# - Uses Test Environment for ServiceNow Change
# - Variable can be used for debugging
$ApprovedTester=@('prvfjpeterson@nd.gov','prvjdkieson@nd.gov')
if ($test) {
Write-Verbose -Message "Running in Test Mode " -Verbose
if ($ApprovedTester -contains $RequestedBy)
{
"You are allowed but others are disabled"
}
else {
Write-Error "Check with freeman script is currenly disabled"
# exit
}
}
#Set ad Default to Hide from End user.
$ServerType="IIS"
$Format="base64"
$KeyType="RSA" #reminder this would need to be set on csr.
$mydate=(Get-Date -Format 'yyyy-MM-dd'|out-string).Trim()
$FriendlyName = $CommonName + "-" +$myDate
#Write-Verbose -Message "Update Module" -Verbose
#Find-Module -Repository ITD_PwshGallery -Name ITD.Infra-Certificate-External.Sectigo |Update-Module -Scope AllUsers
if ($PSCmdlet.ParameterSetName -eq 'Windows') {
Write-Verbose -Message "Validate host" -Verbose
Foreach ($ComputerName in $DestinationServerArray) {
$remotehi=Invoke-Command -ComputerName $ComputerName -ScriptBlock {"hi"} -Credential $Secret:ndgov_svcitdpsuwin
if ($remotehi -eq "hi") {
"Connection to host $ComputerName Succeded"
} else {
"Connection to host $ComputerName failed"
exit
}
}
}
if ($PSCmdlet.ParameterSetName -eq 'Windows') {
Write-Verbose -Message "Retrieve CI from ServiceNow" -Verbose
#We are just pulling appname from first DestinationServer
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$IP=(Resolve-DnsName -Name $DestinationServerArray[0]).IPAddress
$Filter= "ip_address=$ip^operational_status=1"
$Fields=("FQDN","ip_address","Location","model_id","Name","dns_domain","os_domain","Schedule","Environment","sys_class_name","u_nd_application_svc","discovery_source","support_group")
$CI= Get-ITDServiceNowRecord -Table "cmdb_ci_win_server" -Filter $Filter -Fields $Fields -First 1
$ApplicationName=$CI.u_nd_application_svc.display_value
if (!$ApplicationName) {
write-Error "CI NOT FOUND"
exit
}
$customFields = @(
[pscustomobject]@{ name = "ApplicationName"; value = $ApplicationName }
)
}
else { #ParmeterSet Not Windows
Write-Verbose -Message "Retrieve App record from ServiceNow" -Verbose
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$Filter= "name=$ApplicationName"
$Fields=("name")
$CI= Get-ITDServiceNowRecord -Table "cmdb_ci_service_auto" -Filter $Filter -Fields $Fields
if ($CI.name.value -ne $ApplicationName ) {
Write-Error "Could not find $ApplicationName"
exit
}
}
#Got email address now!
$RequesterEmail=Get-ICE-Snowemail -ApplicationName $ApplicationName -Credential $Secret:snow_vmcred
Send-ICE-Mail -recipientsString $RequesterEmail -Jobid $PSUJobId -status "Started" -Message "Check job status"
Write-Verbose -Message "Validate Email Address" -Verbose
$EmailAddressList = $RequesterEmail -split ","
foreach ($e in $EmailAddressList) {
$user = Get-ADUser -Filter "Mail -eq '$e'" -Properties Mail
$group = Get-ADGroup -Filter "Mail -eq '$($e)'" -Properties Mail
if ($user -or $group) {
Write-Verbose -Message "$e Passed testing" -Verbose
}
else {
Write-Error "$e is an invalid email address. Terminating Script"
exit
}
}
$RequesterEmail=Get-ICE-Snowemail -ApplicationName $ApplicationName -Credential $Secret:snow_vmcred
#Set env prod
Set-JDEnvironment -Name prod
Write-Verbose -Verbose "Retire PreviousThumbprint"
$PreviousThumbprint=(Select-JDJson -TableName certcache -CommonName $commonname).Thumbprint
if ($PreviousThumbprint) {
$table=@("certlog","certcache")
Foreach ($t in $table) {
Set-JDJson -TableName $t `
-Where { param($row) $row.CommonName -eq $commonname } `
-Set @{ is_retired = $true; PreviousThumbprint = $PreviousThumbprint } `
-Verbose
} #end of foreach
} #end of if $Previous thumbprint
# Done validation
#
# Do the work
#
#
Write-Verbose -Message "Create CSR" -Verbose
$csr = New-ICE-CSR -commonName $commonName
Write-Verbose -Message "Test CSR" -Verbose
If (Test-ICE-CSR -csrstring $csr) {
"CSR Passed"
}
else {
Write-Error "Not A Valid CSR"
}
$Comments="Enrolled by PSUniversal, Job " + $UAJob.Id + ", User " + $UAJob.Identity.Name + "," + $Comments
if ($ApplicationName)
{
$customFields = @(
@{
name = "ApplicationName"
value = $ApplicationName
}
)
}
Write-Verbose -Message "Setting up params for Enroll-SectigoCertificateRequest" -Verbose
$splat = @{
Csr=$csr
dcvEmail=$RequesterEmail
Comment=$Comments
KeyType=$KeyType
subjAltNames=$SubjectAlternative
}
$b1 = @{
customFields = $customFields
}
if ($customFields) {
$splat = $splat+ $b1
}
$cred=$Secret:SectigoClientSecret
$env:Sectigoclientid = $cred.UserName
$env:SectigoclientSecret = $cred.GetNetworkCredential().Password
Write-Verbose -Message "Enroll-SectigoCertificateRequest" -Verbose
Get-SectigoApiToken
$certRequest = Enroll-SectigoCertificateRequest @Splat
Write-Verbose -Message "Waiting for Cert Status" -Verbose
while ($certstatus -ne "Issued") {
$certstatus=(Get-SectigoCertificate -OrderId $certRequest.sslid).status
Sleep 1
$run= $run + 1
if ($run -gt 60) {
Write-Error "Failed to get issue status after 1 minute..exiting"
exit
}
}
Write-Verbose -Message "Downloading Certificate" -Verbose
$CertRootPath="c:\psautocerts\"
mkdir $CertRootPath 2>$null
$CertPath = (Download-SectigoCertificate -Orderid $certRequest.sslid -Format $Format -CertRootPath $CertRootPath).FullName
Write-Verbose -Message "Generate Password" -Verbose
$pfxPassword= Generate-ICE-PFXPassword
$secure_pfxpassword = ConvertTo-SecureString $pfxPassword -AsPlainText -Force
$pfxCredential = [System.Management.Automation.PSCredential]::new("None", $secure_pfxpassword)
Write-Verbose -Verbose "Convert to pfx"
$results=Convert-ICE-PKS7toPfx -CertFile $CertPath -pfxCredential $pfxCredential
$pfxPath=$results.Fullname
Write-Verbose -Verbose "Load the certificate object"
$collection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$collection.Import($pfxPath, $pfxPassword, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet)
# Display all certificates in the chain
#$collection | Format-List Subject, Issuer, Thumbprint, NotAfter
$foundCerts = $collection.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindBySubjectName, $CommonName, $false)
$ExpiryDate = $foundCerts[0].NotAfter
$Thumbprint=$foundCerts[0].Thumbprint
if ($PSCmdlet.ParameterSetName -eq 'Cloud Service') {
$PfxtoPasswordState=$True
}
if ($PfxtoPasswordState) {
Write-Verbose -Verbose "Save to Password State"
$PasswordStateParams = @{
Title = $FriendlyName;
Description = $Comments ;
ExpiryDate = $ExpiryDate ;
APICreds = $Secret:pwdvault_WindowsCertificates ;
pfxCredential = $pfxCredential;
PfxPath = $pfxPath;
}
$PasswordStateSuccess=Send-ICE-PfxtoPasswordState @PasswordStateParams
}
#Send file to cert store windows only"
if ($PSCmdlet.ParameterSetName -eq 'Windows') {
$CertificatetoCertStore = @{
pfxPath = $pfxPath;
RemoteCertPath = "c:\temp\certificatex.pfx";
DestinationServer = $DestinationServerArray
Credential = $Secret:ndgov_svcitdpsuwin ;
pfxCredential = $pfxCredential;
CertStoreLocation = "Cert:\LocalMachine\MY";
ThumbPrint = $ThumbPrint ;
FriendlyName = $FriendlyName
}
$CertStoreResults=Send-ICE-CertificatetoCertStore @CertificatetoCertStore
$CertStoreResults
}
Write-Verbose -Verbose "Cleaning Up Temp Files"
if (Test-Path -Path $CertPath -PathType Leaf) {
Remove-Item -Path $CertPath -Force -Confirm:$false 2>$null
}
if (Test-Path -Path $pfxPath -PathType Leaf) {
Remove-Item -Path $pfxPath -Force -Confirm:$false 2>$null
}
# Validate the user
$StartDateTime = (Get-Date)
$EndDateTime = $StartDateTime.AddMinutes(1)
$RequestedBy=$UAJob.Identity.Name
if ($PSCmdlet.ParameterSetName -eq 'Cloud Service' -and $PasswordStateSuccess -eq $True ) { $Completed=$true}
if ($PSCmdlet.ParameterSetName -eq 'Windows' -and $CertStoreResults.Success -eq $True) { $Completed=$true}
if ($Completed) {
Write-Verbose -Message "Create CHG request for the work" -Verbose
$ServiceNowEnvironment = "Production" #'Production', 'Test', 'Development'
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$NewITDServiceNowChangeRequestParams = @{
TemplateName = 'NDIT-SPS-PSU Cert Automation Platform'
RequestedByUsername = $RequestedBy.split('@')[0] -replace 'prv';
Category = 'Systems Platforms - Systems';
Subcategory = 'Windows';
Impact = 3;
ShortDescription = "New Certificate Created - PSU Job Id $PSUJobId";
Description = "New Certificate Created - PSU Job Id $PSUJobId";
Justification = "Security Standards require an updated certificate";
Implementation = "PSUniversal execution";
RiskImpactAnalysis = "Low";
BackoutPlan = "Revoke Cert"
TestPlan = "n/a"
WhoIsImpacted = "Windows System Administrators";
StartTime = $StartDateTime
EndTime = $StartDateTime.AddMinutes(1);
AssignmentGroup = 'NDIT-Computer Systems Windows';
ChangeManagerUsername = 'khellman';
ChangeCoordinatorUsername = 'gpgolberg';
AssignedToUsername = $RequestedBy.split('@')[0] -replace 'prv';
}
$CHG = New-ITDServiceNowChangeRequest @NewITDServiceNowChangeRequestParams -Verbose
$CHGNum = $CHG.Number.value
Write-Verbose -Message ("Completing Snow " + $CHG.Number.value) -Verbose
$CompleteITDServiceNowChangeRequestParams = @{
Number = $CHG.Number.value
CloseCode = "Successful"
CloseNotes = ("New Certificate" + $obj.ADDomain + "\" + $obj.SamAccountName + " created.")
}
Complete-ITDServiceNowChangeRequest @CompleteITDServiceNowChangeRequestParams -Verbose
Write-Verbose -Message "Status Success" -Verbose
$Jobstatus = "Success"
}
Else {
Write-Verbose -Message "Status Failure" -Verbose
$JobStatus = "Failure"
}
Send-ICE-Mail -recipientsString $RequesterEmail -Jobid $PSUJobId -status $Jobstatus -Message "Created Standard Change"
$log_psobject=[pscustomobject]@{
Timestamp = (Get-Date)
ParameterSetName = $ParameterSetName
RequestedBy = $RequestedBy
RequesterEmail = $RequesterEmail
CommonName = $CommonName
SubjectAlternative = $SubjectAlternative
DestinationServer = $DestinationServer
PfxtoPasswordState = $PfxtoPasswordState
ApplicationName = $ApplicationName
ExpiryDate = $ExpiryDate
Thumbprint = $Thumbprint
PreviousThumbprint = $PreviousThumbprint
is_retired = $false
}
Write-Verbose -Verbose "Log new transaction to both tables. "
#Cache table common name is the primary key so there should only be an update?
$table=@("certlog","certcache")
Foreach ($t in $table) {
$log_psobject| Add-JDJson -TableName $t -Verbose
}
###########################################
if ($PasswordStateSuccess) {
"Your new Certificate is in PasswordState at: "
" Windows/Certificates/${FriendlyName}"
}
}
@@ -0,0 +1,168 @@
[CmdletBinding(DefaultParameterSetName = 'Windows')]
param(
[Parameter(Mandatory, ParameterSetName = 'Windows')]
[Parameter(Mandatory, ParameterSetName = 'Cloud Service')]
[String]$CommonName,
# Host for Cert Delivery, comma seperated
[Parameter(Mandatory, ParameterSetName = 'Windows')]
[String]$DestinationServer,
# Option for pfx in PasswordState
[Parameter(Mandatory, ParameterSetName = 'Windows')]
[bool]$PfxtoPasswordState,
# AppName CI in CMDB
[Parameter(Mandatory, ParameterSetName = 'Cloud Service')]
[String]$ApplicationName
)
#PSU Reassignment per Zacks standards
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$DestinationServerArray = $DestinationServer -split ","
if ($PSCmdlet.ParameterSetName -eq 'Windows') {
Write-Verbose -Message "Validate host" -Verbose
Foreach ($ComputerName in $DestinationServerArray) {
$remotehi=Invoke-Command -ComputerName $ComputerName -ScriptBlock {"hi"} -Credential $Secret:ndgov_svcitdpsuwin
if ($remotehi -eq "hi") {
"Connection to host $ComputerName Succeded"
} else {
"Connection to host $ComputerName failed"
exit
}
}
}
if ($PSCmdlet.ParameterSetName -eq 'Windows') {
Write-Verbose -Message "Retrieve CI from ServiceNow" -Verbose
#We are just pulling appname from first DestinationServer
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$IP=(Resolve-DnsName -Name $DestinationServerArray[0]).IPAddress
$Filter= "ip_address=$ip^operational_status=1"
$Fields=("FQDN","ip_address","Location","model_id","Name","dns_domain","os_domain","Schedule","environment","sys_class_name","u_nd_application_svc","discovery_source","support_group")
$CI= Get-ITDServiceNowRecord -Table "cmdb_ci_win_server" -Filter $Filter -Fields $Fields -First 1
$ApplicationName=$CI.u_nd_application_svc.display_value
if (!$ApplicationName) {
write-Error "CI NOT FOUND"
exit
}
$customFields = @(
[pscustomobject]@{ name = "ApplicationName"; value = $ApplicationName }
)
}
else { #ParmeterSet Not Windows
Write-Verbose -Message "Retrieve App record from ServiceNow" -Verbose
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$Filter= "name=$ApplicationName"
$Fields=("name")
$CI= Get-ITDServiceNowRecord -Table "cmdb_ci_service_auto" -Filter $Filter -Fields $Fields
if ($CI.name.value -ne $ApplicationName ) {
Write-Error "Could not find $ApplicationName"
exit
}
}
Write-Verbose -Message "Validate Email Address" -Verbose
$RequesterEmail=Get-ICE-Snowemail -ApplicationName $ApplicationName -Credential $Secret:snow_vmcred
$EmailAddressList = $RequesterEmail -split ","
foreach ($e in $EmailAddressList) {
$user = Get-ADUser -Filter "Mail -eq '$e'" -Properties Mail
$group = Get-ADGroup -Filter "Mail -eq '$($e)'" -Properties Mail
if ($user -or $group) {
Write-Verbose -Message "$e Passed testing" -Verbose
}
else {
Write-Error "$e is an invalid email address. Terminating Script"
exit
}
}
#Set env prod
Write-Verbose -Verbose "Set DB Environment"
Set-JDEnvironment -Name prod
Write-Verbose -Verbose "Remoting to other server to get cert info"
$ComputerName=$DestinationServerArray[0]
$OldCert=Get-ICE-RemoteCertInfo -ComputerName $ComputerName -CommonName $CommonName -Credential $Secret:ndgov_svcitdpsuwin
Write-Verbose -Verbose "Old Cert"
$OldCert|fl
$ExpiryDate=$OldCert.NotAfter
$subjectAlternative = $OldCertsubjectAlternative
$ParameterSetName=$PSCmdlet.ParameterSetName
$SubjectAlternative = $OldCert.subjectAlternative
$ExpiryDate = $OldCert.NotAfter
$Thumbprint=$OldCert.Thumbprint
$PreviousThumbprint = $false
Write-Verbose -Verbose "Create Powershell object for Logging"
$log_psobject=[pscustomobject]@{
Timestamp = (Get-Date)
ParameterSetName = $ParameterSetName
RequestedBy = $RequestedBy
RequesterEmail = $RequesterEmail
CommonName = $CommonName
Environment = $CI.environment.value
NotBefore = $OldCert.NotBefore
SubjectAlternative = $SubjectAlternative
DestinationServer = $DestinationServer
PfxtoPasswordState = $PfxtoPasswordState
ApplicationName = $ApplicationName
ExpiryDate = $ExpiryDate
Thumbprint = $Thumbprint
PreviousThumbprint = $PreviousThumbprint
is_retired = $false
}
$bla=$log_psobject|Out-String
Write-Host $bla
#$Result = Read-Host "Does this information look correct y/n"
$Result = "y" #forcing
if ($result -eq "y") {
Write-Verbose -Verbose "Log new transaction to both tables. "
#Cache table common name is the primary key so there should only be an update?
$table=@("certlog","certcache")
Foreach ($t in $table) {
$log_psobject| Add-JDJson -TableName $t -Verbose
}
}
else {
"Did not Save! You are NOT Registered!"
}
Write-Verbose -Verbose "Installing Client Module"
$InstallParams= @{
DestinationServer = $DestinationServer
Email = $RequesterEmail
PSUJobId = $PSUJobId
Credential = $Secret:ndgov_svcitdpsuwin
}
Install-ICE-Client @InstallParams
@@ -0,0 +1,17 @@
#Get-MaintenanceWindow -Credential $Secret:snow_vmcred
Param (
$DestinationServer
)
$Scriptblock = {
$config="C:\scripts\ITD.Infra-Certificate-External.Client\Data\IISBindingAutoConfig.config"
Test-Path $config
}
ForEach ($ComputerName in $DestinationServer ) {
$result=Invoke-Command -ComputerName $ComputerName -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock $Scriptblock
$computername + ":" + $result
}
@@ -0,0 +1,27 @@
[CmdletBinding()]
param (
[Parameter(Mandatory = $true,
HelpMessage = "Common Name for cert")]
[string]
$CommonName
)
Import-Module ITD.Infra-Certificate-External.JsonDB
Write-Verbose -Verbose "Set DB Environment"
Set-JDEnvironment -Name prod
$PreviousThumbprint=(Select-JDJson -TableName certcache -CommonName $commonname).Thumbprint
#Unreg from cert log
if ($PreviousThumbprint) {
$table=@("certlog")
Foreach ($t in $table) {
Set-JDJson -TableName $t `
-Where { param($row) $row.CommonName -eq $commonname } `
-Set @{ is_retired = $true; PreviousThumbprint = 'OLD-000-XYZ' } `
-Verbose
} #end of foreach
} #end of if $Previous thumbprint
#delete from certcache
Remove-JDJson -TableName certcache -Where { param($o) $o.commonname -eq $commonname }
@@ -0,0 +1,17 @@
[CmdletBinding()]
param(
[Parameter(Mandatory)]
$DestinationServer,
$Email
)
$PSUJobId = $UAJob.Id
$InstallParams= @{
DestinationServer = $DestinationServer
Email = $Email
PSUJobId = $PSUJobId
Credential = $Secret:ndgov_svcitdpsuwin
}
Install-ICE-Client @InstallParams
@@ -0,0 +1,31 @@
Param(
[Parameter(Mandatory = $true)]
[string[]]
$ComputerName = $null,
[ValidateSet('All Day Every Day',
'Weekdays 700 to 1800',
'All Week 500 to 2300'
)]
[string]
$SupportHours
)
$Func = {
param($C, $SwSupportHours)
Write-Verbose -Message "Add to Solarwinds" -Verbose
Import-SWDiscovery -ComputerName $C -Integration ServiceNow
Start-Sleep -Seconds 10
Write-Verbose -Message "Set Solarwinds node custom properties if parameter exists" -Verbose
If($PSBoundParameters.ContainsKey('SupportHours')){
Write-Verbose -Message "SupportHours $SwSupportHours." -Verbose
Set-SWNodeCustomProperty -ComputerName $C -Property SupportHours -Value $SwSupportHours
}
}
$ComputerName | ForEach-Object {
Invoke-Command -ComputerName itdslrwnds.nd.gov -ScriptBlock $Func -ArgumentList $_,$SupportHours -Credential $Secret:ndgov_svcitdiaasauto
}
@@ -0,0 +1,10 @@
Param(
[Parameter(Mandatory = $true)]
[string[]]
$ComputerName = $null
)
ForEach ($cn in $ComputerName) {
Write-Verbose -Message "Attempt Solarwinds removal for $cn" -Verbose
Remove-ITDSolarwindsNode -ComputerName $cn -Credential $Secret:ndgov_svcitdiaasauto -Verbose
}
@@ -0,0 +1,38 @@
Write-Verbose -Message "Prepare variables based on PSU server" -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServiceNowEnvironment = "Test"
}
"ITDWINAUTOP1" {
$ServiceNowEnvironment = "Production"
}
}
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
<#
Write-Verbose -Message "Retrieve List of all Server Build Request request items from ServiceNow where closed_at is Yesterday and request_type is Change" -Verbose
$Filter = 'cat_item=c64e27af47244610b7853238436d435d^variables.3bf9fc3b47240a10b7853238436d430b=Change^closed_atONYesterday@javascript:gs.beginningOfYesterday()@javascript:gs.endOfYesterday()'
####### 'cat_item=c64e27af47244610b7853238436d435d^variables.3bf9fc3b47240a10b7853238436d430b=Change^closed_atONYesterday@javascript:gs.beginningOfYesterday()@javascript:gs.endOfYesterday()'
$CompletedRitms = Get-ITDServiceNowRecord -ItemType 'Request Item' -Filter $Filter
Write-Verbose -Message ("Found " + @($CompletedRitms).count + " completed Ritms.")
#>
$CompletedRitms = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number RITM0269022
ForEach($Ritm in $CompletedRITMs){
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number ($Ritm.number.value) -IncludeCustomVariable -IncludeVariableSet
# loop each VM row
ForEach($row in $Ritm.VariableSet){
# resolve sys_id to host name
$CmdbCi = Get-ITDServiceNowRecord -Table cmdb_ci -SysId $row.host_name_ref
Write-Verbose -Message ("Start " + $Ritm.number.value + " server " + $row.host_name_ref + ', ' + $CmdbCi.fqdn.display_value) -Verbose
# run solarwinds import
$Func = {
param ($c)
Write-Verbose -Message "Attempting to import $c to Solarwinds"
Import-SWDiscovery -ComputerName $c
}
Invoke-Command -ComputerName itdslrwnds.nd.gov -ScriptBlock $Func -ArgumentList $CmdbCi.fqdn.display_value -Credential $Secret:ndgov_svcitdiaasauto
}
}
@@ -0,0 +1,36 @@
Param(
[string]
$Name,
[ValidateSet(
'Infra-ActiveDirectory.Object',
'Infra-Azure.VirtualMachine',
'Infra-Certificate-External.Sectigo',
'Infra-Monitoring-Solarwinds',
'Infra-VMware.Administration',
'Infra-VMware.VirtualMachine',
'Infra-VMware.Snapshot',
'ITD-WindowsServer.FileManagement',
'ITD-WindowsServer.General',
'ITD-WindowsServer.Lifecycle',
'Shared-Powerschool'
)]
[string]
$Path
)
switch ($Path){
<# example switch condition and actions
{ $_ -like "App-XXXXX"} {$TagNamesEnforced = @('Shared-XXXXX_Modify)}
#>
{ $_ -eq "Infra-ActiveDirectory.Object" } { $TagNamesEnforced = @('ITD-WindowsServer_Modify') }
{ $_ -like "Infra-Azure.*"} {$TagNamesEnforced = @('Infra-VMware_Modify')}
{ $_ -like "Infra-Monitoring-Solarwinds*" } { $TagNamesEnforced = @('ITD-WindowsServer_Modify') }
{ $_ -like "Infra-Certificate-External.Sectigo*" } { $TagNamesEnforced = @('Infra-Certificate_Modify') }
{ $_ -like "Infra-VMware*" } { $TagNamesEnforced = @('Infra-VMware_Modify') }
{ $_ -like "ITD-WindowsServer*" } { $TagNamesEnforced = @('ITD-WindowsServer_Modify') }
{ $_ -like "Shared-PowerSchool*" } { $TagNamesEnforced = @('Shared-PowerSchool_Modify') }
}
New-PSUScript -Name $Name -Path "$Path\$Name" -Tag @($TagNamesEnforced) -ScriptBlock {# It all starts with a single line of powershell code.
}
@@ -0,0 +1,42 @@
#######
Write-Verbose -Message "Determine if ITD_PwshGallery is registered" -Verbose
If(Get-PSRepository -Name ITD_PwshGallery -ErrorAction SilentlyContinue){
Write-Verbose -Message "ITD_PwshGallery found." -Verbose
} Else {
$RegisterPSRepositoryParams = @{
Name = 'ITD_PwshGallery';
InstallationPolicy = 'Trusted';
SourceLocation = 'https://powershell.nd.gov/ITD_PwshGallery/nuget/';
PublishLocation = 'https://powershell.nd.gov/ITD_PwshGallery/nuget/';
ScriptSourceLocation = 'https://powershell.nd.gov/ITD_PwshGallery/nuget/';
ScriptPublishLocation = 'https://powershell.nd.gov/ITD_PwshGallery/nuget/';
}
Register-PSRepository @RegisterPSRepositoryParams
}
Write-Verbose -Message "Retrieve list of all available modules and versions"
$ITDModules = Find-Module -Name "ITD.*" -Repository ITD_PwshGallery
Write-Verbose -Message "Compare local module versions to repository versions, and update if needed"
ForEach($ITDModule in $ITDModules){
$VersionsAvailable = $null
$MostRecentVersion = $null
$RepoVersion = $null
$VersionsAvailable = Get-Module -Name $ITDModule.name -ListAvailable
$MostRecentVersion = $VersionsAvailable | Sort-Object Version -Descending | Select -First 1
$RepoVersion = $ITDModule.Version
If($null -eq $MostRecentVersion) {
Write-Verbose -Message ($ITDModule.Name + " was not found locally, installing module now.") -Verbose
Install-Module -Name $ITDModule.Name -Scope AllUsers -Repository ITD_PwshGallery
} Else {
Write-Verbose -Message ($ITDModule.Name + " was found locally, comparing versions and updating if needed..") -Verbose
Write-Host -Message ($ITDModule.Name)
Write-Host -Message ("Local version is " + $MostRecentVersion.Version)
Write-Host -Message ("The Repo version is " + $RepoVersion)
Write-Host -Message ("")
Update-Module -Name $ITDModule.Name -Scope AllUsers -Verbose
}
}
@@ -0,0 +1 @@
# It all starts with a single line of powershell code.
@@ -0,0 +1,131 @@
<#
.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
#>
<# Scheduled Task metadata
General
Get IPs for PA
run as ndgov\!itdvcenterppa
run whether user is logged on or not
Triggers
Daily, 11am
Daily, 11pm
Actions
old-C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noninteractive -file "C:\itdscript\GetIPs.ps1"
new-"C:\Program Files\PowerShell\7\pwsh.exe" -noninteractive -file "F:\GetVMwareVMGuestIPsForPA\GetVMwareVMGuestIPsForPA.ps1"
Settings
allow task to be run on demand
stop the task if it runs longer than 1 hour -eq $true
if the running task does not end when requested, force it to stop
#>
$TimeStamp = Get-Date -UFormat "%Y%m%d%H%M%S"
#Connect
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcauto
##Windows
#Output File
$OutFileWin = "c:\inetpub\wwwroot\Win.txt"
#$Date = Get-Date -UFormat "%Y%m%d%H%M%S"
Get-Item -Path $OutFileWin | Copy-Item -Destination "F:\GetVMwareVMGuestIPsForPA\Backup\Win\$Timestamp-Win.txt"
Remove-Item $OutFileWin
Start-Sleep -Seconds 5
#Get Powered On VM's
$vmwin = get-VM | Where-Object { $_.PowerState -eq "PoweredOn" `
-and ($_.GuestID -eq "windows7Guest" `
-or $_.GuestID -eq "windows7_64Guest" `
-or $_.GuestID -eq "windows7Server64Guest" `
-or $_.GuestID -eq "windows8_64Guest" `
-or $_.GuestID -eq "windows8Server64Guest" `
-or $_.GuestID -eq "windows9Server64Guest" `
-or $_.GuestID -eq "winLonghorn64Guest" `
-or $_.GuestID -eq "winLonghornGuest" `
-or $_.GuestID -eq "winNetStandardGuest" `
-or $_.GuestID -eq "winNetEnterpriseGuest" `
-or $_.GuestID -eq "windows9_64Guest" `
-or $_.GuestID -eq "windows2019srv_64Guest" `
-or $_.GuestID -eq "windows2019srvNext_64Guest") }
$vmviewwin = $vmwin | Get-View
$Outputwin = ""
#Loop through VM's, NIC's, and IP addresses.
Foreach ($v in $vmviewwin) {
Foreach ($nic in $v.Guest.Net) {
Foreach ($IP in $nic.IPAddress) {
If ($IP -notlike "fe80*" -and $IP -notlike "192.168.*" -and $IP -notlike "172.16*") {
$OutputWin += $IP + "`n"
}
}
}
}
#If ($Outputwin -ne "") {$OutputWin | Out-File $OutFileWin -Encoding utf8 -NoNewline}
If ($Outputwin -ne "") { $OutputWin | Out-File $OutFileWin -Encoding ASCII -NoNewline }
##Linux
#Output File
$OutFileLin = "c:\inetpub\wwwroot\Lin.txt"
$Date = Get-Date -UFormat "%Y%m%d%H%M%S"
Get-Item -Path $OutFileLin | Copy-Item -Destination "F:\GetVMwareVMGuestIPsForPA\Backup\Lin\$Timestamp-Lin.txt"
Remove-Item $OutFileLin
Start-Sleep -Seconds 5
#Get Powered On VM's
$vmLin = get-VM | Where-Object { $_.PowerState -eq "PoweredOn" `
-and ($_.GuestID -eq "centos6_64Guest" `
-or $_.GuestID -eq "centos64Guest" `
-or $_.GuestID -eq "centos7_64Guest" `
-or $_.GuestID -eq "oracleLinux64Guest" `
-or $_.GuestID -eq "oracleLinux7_64Guest" `
-or $_.GuestID -eq "rhel4Guest" `
-or $_.GuestID -eq "rhel5Guest" `
-or $_.GuestID -eq "rhel5_64Guest" `
-or $_.GuestID -eq "rhel6Guest" `
-or $_.GuestID -eq "rhel6_64Guest" `
-or $_.GuestID -eq "rhel7_64Guest" `
-or $_.GuestID -eq "rhel8_64Guest" `
-or $_.GuestID -eq "rhel9_64Guest" `
-or $_.GuestID -eq "sles11_64Guest" `
-or $_.GuestID -eq "sles12_64Guest" `
-or $_.GuestID -eq "ubuntu64Guest") }
$vmviewlin = $vmLin | Get-View
$OutputLin = ""
#Loop through VM's, NIC's, and IP addresses.
Foreach ($v in $vmviewlin) {
Foreach ($nic in $v.Guest.Net) {
Foreach ($IP in $nic.IPAddress) {
If ($IP -notlike "fe80*" -and $IP -notlike "192.168.*" -and $IP -notlike "172.16*") {
$OutputLin += $IP + "`n"
}
}
}
}
#If ($OutputLin -ne "") {$OutputLin | Out-File $OutFileLin -Encoding utf8 -NoNewline}
If ($OutputLin -ne "") { $OutputLin | Out-File $OutFileLin -Encoding ASCII -NoNewline }
Disconnect-ITDvCenter
@@ -0,0 +1,270 @@
<#
.SYNOPSIS
Daily HPE OneView enclosure and server inventory for PowerBI trending and lifecycle planning.
.DESCRIPTION
Iterates across all configured HPE OneView appliances, collecting enclosure and server
hardware metadata including compute capacity, power state, and server profile assignment.
Exports timestamped CSVs and inserts into SQL each run.
Append daily runs to build a historical dataset for PowerBI trend analysis and
physical hardware purchasing / lifecycle decisions.
Appliances processed:
itdoneviewp1.nd.gov - Rack servers only (no enclosures)
itdbissyncompp1.nd.gov - Synergy enclosures + servers
itdmdnsyncompp1.nd.gov - Synergy enclosures + servers
.NOTES
Run the following DDL once to create the destination tables:
DROP TABLE IF EXISTS [dbo].[VMware_Trends_Enclosure]
CREATE TABLE [dbo].[VMware_Trends_Enclosure] (
[ReportDate] DATETIME2 NOT NULL,
[ApplianceConnection] NVARCHAR(100) NULL,
[EnclosureName] NVARCHAR(255) NOT NULL,
[EnclosureModel] NVARCHAR(255) NULL,
[EnclosureSerialNumber] NVARCHAR(100) NULL,
[Status] NVARCHAR(50) NULL,
[DeviceBayCount] INT NULL
)
DROP TABLE IF EXISTS [dbo].[VMware_Trends_Server]
CREATE TABLE [dbo].[VMware_Trends_Server] (
[ReportDate] DATETIME2 NOT NULL,
[ApplianceConnection] NVARCHAR(100) NULL,
[EnclosureName] NVARCHAR(255) NULL,
[BayNumber] INT NULL,
[ServerHardwareName] NVARCHAR(255) NOT NULL,
[ServerName] NVARCHAR(255) NULL,
[ServerModel] NVARCHAR(255) NULL,
[ServerSerialNumber] NVARCHAR(100) NULL,
[Status] NVARCHAR(50) NULL,
[PowerState] NVARCHAR(50) NULL,
[ServerProfileName] NVARCHAR(255) NULL,
[ProcessorType] NVARCHAR(255) NULL,
[ProcessorCount] INT NULL,
[MemoryGB] DECIMAL(10,2) NULL,
[FormFactor] NVARCHAR(100) NULL
)
EnclosureName and BayNumber are NULL for rack-mounted servers not seated in an enclosure.
ServerName is the iLO/DNS hostname populated once a server profile is assigned.
#>
[CmdletBinding()]
param(
)
#region --- Setup ---------------------------------------------------------------
[string[]] $OVHostnames = @(
'itdoneviewp1.nd.gov',
'itdbissyncompp1.nd.gov',
'itdmdnsyncompp1.nd.gov'
)
[string] $OutputPath = 'C:\temp\OV_Trends\'
[string] $ServerInstance = 'itdintsql22p1.nd.gov\INTSQL22P1'
[string] $Database = 'ITD-Systems-Automation'
[string] $EnclosureTable = 'VMware_Trends_Enclosure'
[string] $ServerTable = 'VMware_Trends_Server'
[System.Management.Automation.PSCredential] $OVCredential = $Secret:ndgov_svcitdvmhpe
[System.Management.Automation.PSCredential] $SqlCredential = $Secret:sql_itdpsu1
$RunDate = Get-Date
$DateStamp = $RunDate.ToString('yyyyMMdd')
$Timestamp = $RunDate.ToString('yyyy-MM-dd')
if (-not (Test-Path -Path $OutputPath)) {
New-Item -ItemType Directory -Path $OutputPath | Out-Null
}
Start-Transcript -Path (Join-Path $OutputPath "OVServerInventory_$DateStamp.log") -Append
#endregion
#region --- Collect Data From All Appliances -----------------------------------
$AllEnclosureResults = [System.Collections.Generic.List[PSCustomObject]]::new()
$AllServerResults = [System.Collections.Generic.List[PSCustomObject]]::new()
foreach ($OVHostname in $OVHostnames) {
Write-Verbose "Connecting to HPE OneView: $OVHostname"
Connect-OVMgmt -Hostname $OVHostname -Credential $OVCredential -AuthLoginDomain nd.gov -LoginAcknowledge
#--- Enclosures ------------------------------------------------------------
Write-Verbose "[$OVHostname] Gathering enclosures..."
$Enclosures = Get-OVEnclosure
# Build URI map for server lookups (only populated if there are enclosures)
$EnclosureUriMap = @{}
foreach ($Enclosure in $Enclosures) {
$EnclosureUriMap[$Enclosure.uri] = $Enclosure.name
$AllEnclosureResults.Add([PSCustomObject]@{
ReportDate = $Timestamp
ApplianceConnection = $OVHostname
EnclosureName = $Enclosure.name
EnclosureModel = $Enclosure.model
EnclosureSerialNumber = $Enclosure.serialNumber
Status = $Enclosure.status
DeviceBayCount = ($Enclosure.deviceBays | Measure-Object).Count
})
}
#--- Servers ---------------------------------------------------------------
Write-Verbose "[$OVHostname] Gathering servers..."
$Servers = Get-OVServer | Where-Object { $_.serverName -like 'itdvm*' }
# Build profile URI map for this appliance
$ProfileUriMap = @{}
Get-OVServerProfile | ForEach-Object {
$ProfileUriMap[$_.uri] = $_.name
}
Write-Verbose "[$OVHostname] Processing $($Servers.Count) servers..."
foreach ($Server in $Servers) {
$EnclosureName = if ($Server.locationUri) {
$EnclosureUriMap[$Server.locationUri]
} else {
$null
}
$ProfileName = if ($Server.serverProfileUri) {
$ProfileUriMap[$Server.serverProfileUri]
} else {
$null
}
$MemoryGB = if ($null -ne $Server.memoryMb -and $Server.memoryMb -gt 0) {
[Math]::Round($Server.memoryMb / 1024, 2)
} else {
$null
}
$AllServerResults.Add([PSCustomObject]@{
ReportDate = $Timestamp
ApplianceConnection = $OVHostname
EnclosureName = $EnclosureName
BayNumber = if ($null -ne $Server.position) { [int]$Server.position } else { $null }
ServerHardwareName = $Server.name
ServerName = $Server.serverName
ServerModel = $Server.model
ServerSerialNumber = $Server.serialNumber
Status = $Server.status
PowerState = $Server.powerState
ServerProfileName = $ProfileName
ProcessorType = $Server.processorType
ProcessorCount = if ($null -ne $Server.processorCount) { [int]$Server.processorCount } else { $null }
MemoryGB = $MemoryGB
FormFactor = $Server.formFactor
})
}
Disconnect-OVMgmt
Write-Verbose "[$OVHostname] Disconnected."
}
#endregion
#region --- Export CSVs --------------------------------------------------------
$EnclosureCsv = Join-Path $OutputPath "OVEnclosures_$DateStamp.csv"
$ServerCsv = Join-Path $OutputPath "OVServers_$DateStamp.csv"
$AllEnclosureResults | Export-Csv -Path $EnclosureCsv -NoTypeInformation
$AllServerResults | Export-Csv -Path $ServerCsv -NoTypeInformation
Write-Verbose "Exported $($AllEnclosureResults.Count) enclosure records to: $EnclosureCsv"
Write-Verbose "Exported $($AllServerResults.Count) server records to: $ServerCsv"
#endregion
#region --- SQL Insert: Enclosures ---------------------------------------------
$EnclosureTable_DT = [System.Data.DataTable]::new()
$EnclosureColDefs = [ordered]@{
ReportDate = [datetime]
ApplianceConnection = [string]
EnclosureName = [string]
EnclosureModel = [string]
EnclosureSerialNumber = [string]
Status = [string]
DeviceBayCount = [int]
}
foreach ($Col in $EnclosureColDefs.GetEnumerator()) {
$Column = [System.Data.DataColumn]::new($Col.Key, $Col.Value)
$Column.AllowDBNull = $true
[void]$EnclosureTable_DT.Columns.Add($Column)
}
foreach ($Row in $AllEnclosureResults) {
$DataRow = $EnclosureTable_DT.NewRow()
foreach ($Col in $EnclosureColDefs.Keys) {
$Val = $Row.$Col
$DataRow[$Col] = if ($null -ne $Val) { $Val } else { [DBNull]::Value }
}
[void]$EnclosureTable_DT.Rows.Add($DataRow)
}
Write-SqlTableData -ServerInstance $ServerInstance -DatabaseName $Database -SchemaName 'dbo' `
-TableName $EnclosureTable -Credential $SqlCredential -InputData $EnclosureTable_DT
Write-Verbose "Inserted $($EnclosureTable_DT.Rows.Count) enclosure records into [$Database].[dbo].[$EnclosureTable]"
#endregion
#region --- SQL Insert: Servers ------------------------------------------------
$ServerTable_DT = [System.Data.DataTable]::new()
$ServerColDefs = [ordered]@{
ReportDate = [datetime]
ApplianceConnection = [string]
EnclosureName = [string]
BayNumber = [int]
ServerHardwareName = [string]
ServerName = [string]
ServerModel = [string]
ServerSerialNumber = [string]
Status = [string]
PowerState = [string]
ServerProfileName = [string]
ProcessorType = [string]
ProcessorCount = [int]
MemoryGB = [decimal]
FormFactor = [string]
}
foreach ($Col in $ServerColDefs.GetEnumerator()) {
$Column = [System.Data.DataColumn]::new($Col.Key, $Col.Value)
$Column.AllowDBNull = $true
[void]$ServerTable_DT.Columns.Add($Column)
}
foreach ($Row in $AllServerResults) {
$DataRow = $ServerTable_DT.NewRow()
foreach ($Col in $ServerColDefs.Keys) {
$Val = $Row.$Col
$DataRow[$Col] = if ($null -ne $Val) { $Val } else { [DBNull]::Value }
}
[void]$ServerTable_DT.Rows.Add($DataRow)
}
Write-SqlTableData -ServerInstance $ServerInstance -DatabaseName $Database -SchemaName 'dbo' `
-TableName $ServerTable -Credential $SqlCredential -InputData $ServerTable_DT
Write-Verbose "Inserted $($ServerTable_DT.Rows.Count) server records into [$Database].[dbo].[$ServerTable]"
#endregion
#region --- Cleanup ------------------------------------------------------------
Stop-Transcript
#endregion
@@ -0,0 +1,192 @@
<#
.SYNOPSIS
Daily VMware Cluster metadata report for PowerBI trending and capacity planning.
.DESCRIPTION
Collects cluster-level metadata from vCenter including DRS/HA configuration,
aggregate compute capacity, and effective resource availability.
Exports a timestamped CSV and inserts into SQL each run.
Append daily runs to build a historical dataset for PowerBI trend analysis.
.NOTES
Run the following DDL once to create the destination table:
DROP TABLE IF EXISTS [dbo].[VMware_Trends_Cluster]
CREATE TABLE [dbo].[VMware_Trends_Cluster] (
[ReportDate] DATETIME2 NOT NULL,
[ClusterName] NVARCHAR(255) NOT NULL,
[Datacenter] NVARCHAR(100) NULL,
[DrsEnabled] BIT NOT NULL,
[DrsMode] NVARCHAR(50) NULL,
[HaEnabled] BIT NOT NULL,
[HostCount] INT NULL,
[EffectiveHostCount] INT NULL,
[TotalCpuCores] INT NULL,
[TotalCpuMhz] INT NULL,
[EffectiveCpuMhz] INT NULL,
[TotalMemoryGB] DECIMAL(10,2) NULL,
[EffectiveMemoryGB] DECIMAL(10,2) NULL,
[UsedMemoryGB] DECIMAL(10,2) NULL,
[VMCount] INT NULL
)
TotalCpuMhz, EffectiveCpuMhz, TotalMemoryGB, and EffectiveMemoryGB come from
vCenter's cluster summary (real-time aggregate).
UsedMemoryGB is summed from each host's current MemoryUsageGB.
TotalCpuCores is summed from each host's hardware CpuInfo.
#>
[CmdletBinding()]
param(
)
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcro
#region --- Setup ---------------------------------------------------------------
[string] $OutputPath = 'C:\temp\VM_Trends\'
[string] $ServerInstance = 'itdintsql22p1.nd.gov\INTSQL22P1'
[string] $Database = 'ITD-Systems-Automation'
[string] $Table = 'VMware_Trends_Cluster'
[System.Management.Automation.PSCredential] $SqlCredential = $Secret:sql_itdpsu1
$RunDate = Get-Date
$DateStamp = $RunDate.ToString('yyyyMMdd')
$Timestamp = $RunDate.ToString('yyyy-MM-dd')
if (-not (Test-Path -Path $OutputPath)) {
New-Item -ItemType Directory -Path $OutputPath | Out-Null
}
Start-Transcript -Path (Join-Path $OutputPath "ClusterMetadataReport_$DateStamp.log") -Append
#endregion
#region --- Build Cluster -> Datacenter Lookup ---------------------------------
Write-Verbose 'Building cluster-to-datacenter map...'
$ClusterDatacenterMap = @{}
Get-Datacenter | ForEach-Object {
$DatacenterName = $_.Name
Get-Cluster -Location $_ | ForEach-Object {
$ClusterDatacenterMap[$_.Name] = $DatacenterName
}
}
#endregion
#region --- Collect Cluster Data -----------------------------------------------
Write-Verbose 'Gathering clusters...'
$AllClusters = Get-Cluster
Write-Verbose "Processing $($AllClusters.Count) clusters..."
$Results = foreach ($Cluster in $AllClusters) {
$Summary = $Cluster.ExtensionData.Summary # reuse for all summary fields
#--- Aggregate host-level stats that vCenter summary does not expose
$ClusterHosts = Get-VMHost -Location $Cluster
$TotalCpuCores = ($ClusterHosts | ForEach-Object {
$_.ExtensionData.Hardware.CpuInfo.NumCpuCores
} | Measure-Object -Sum).Sum
$UsedMemoryGB = [Math]::Round(
($ClusterHosts | Measure-Object -Property MemoryUsageGB -Sum).Sum, 2
)
$VMCount = ($ClusterHosts | ForEach-Object {
($_.ExtensionData.Vm | Measure-Object).Count
} | Measure-Object -Sum).Sum
#--- Capacity from cluster summary
$TotalCpuMhz = $Summary.TotalCpu # MHz
$EffectiveCpuMhz = $Summary.EffectiveCpu # MHz
$TotalMemoryGB = [Math]::Round($Summary.TotalMemory / 1GB, 2) # bytes -> GB
$EffectiveMemGB = [Math]::Round($Summary.EffectiveMemory / 1KB, 2) # MB -> GB
[PSCustomObject]@{
ReportDate = $Timestamp
ClusterName = $Cluster.Name
Datacenter = $ClusterDatacenterMap[$Cluster.Name]
DrsEnabled = $Cluster.DrsEnabled
DrsMode = $Cluster.DrsAutomationLevel
HaEnabled = $Cluster.HAEnabled
HostCount = $Summary.NumHosts
EffectiveHostCount = $Summary.NumEffectiveHosts
TotalCpuCores = [int]$TotalCpuCores
TotalCpuMhz = $TotalCpuMhz
EffectiveCpuMhz = $EffectiveCpuMhz
TotalMemoryGB = $TotalMemoryGB
EffectiveMemoryGB = $EffectiveMemGB
UsedMemoryGB = $UsedMemoryGB
VMCount = [int]$VMCount
}
}
#endregion
#region --- Export CSV ---------------------------------------------------------
$OutputFile = Join-Path $OutputPath "ClusterMetadata_$DateStamp.csv"
$Results | Export-Csv -Path $OutputFile -NoTypeInformation
Write-Verbose "Exported $($Results.Count) cluster records to: $OutputFile"
#endregion
#region --- SQL Insert ---------------------------------------------------------
$DataTable = [System.Data.DataTable]::new()
$ColDefs = [ordered]@{
ReportDate = [datetime]
ClusterName = [string]
Datacenter = [string]
DrsEnabled = [bool]
DrsMode = [string]
HaEnabled = [bool]
HostCount = [int]
EffectiveHostCount = [int]
TotalCpuCores = [int]
TotalCpuMhz = [int]
EffectiveCpuMhz = [int]
TotalMemoryGB = [decimal]
EffectiveMemoryGB = [decimal]
UsedMemoryGB = [decimal]
VMCount = [int]
}
foreach ($Col in $ColDefs.GetEnumerator()) {
$Column = [System.Data.DataColumn]::new($Col.Key, $Col.Value)
$Column.AllowDBNull = $true
[void]$DataTable.Columns.Add($Column)
}
foreach ($Row in $Results) {
$DataRow = $DataTable.NewRow()
foreach ($Col in $ColDefs.Keys) {
$Val = $Row.$Col
$DataRow[$Col] = if ($null -ne $Val) { $Val } else { [DBNull]::Value }
}
[void]$DataTable.Rows.Add($DataRow)
}
$SqlParams = @{
ServerInstance = $ServerInstance
DatabaseName = $Database
SchemaName = 'dbo'
TableName = $Table
Credential = $SqlCredential
InputData = $DataTable
}
Write-SqlTableData @SqlParams
Write-Verbose "Inserted $($DataTable.Rows.Count) cluster records into [$Database].[dbo].[$Table]"
#endregion
Disconnect-ITDvCenter
#region --- Cleanup -------------------------------------------------------------
Stop-Transcript
#endregion
@@ -0,0 +1,216 @@
<#
.SYNOPSIS
Daily VMware Host metadata report for PowerBI trending and hardware capacity planning.
.DESCRIPTION
Collects ESXi host metadata from vCenter including hardware, compute capacity, and
version information. Exports a timestamped CSV and inserts into SQL each run.
Append daily runs to build a historical dataset for PowerBI trend analysis and
physical hardware purchasing / lifecycle decisions.
.NOTES
Run the following DDL once to create the destination table:
DROP TABLE IF EXISTS [dbo].[VMware_Trends_Host]
CREATE TABLE [dbo].[VMware_Trends_Host] (
[ReportDate] DATETIME2 NOT NULL,
[HostName] NVARCHAR(255) NOT NULL,
[Datacenter] NVARCHAR(100) NULL,
[Cluster] NVARCHAR(100) NULL,
[ConnectionState] NVARCHAR(50) NULL,
[PowerState] NVARCHAR(50) NULL,
[InMaintenanceMode] BIT NOT NULL,
[Model] NVARCHAR(255) NULL,
[ProcessorType] NVARCHAR(255) NULL,
[CpuSockets] INT NULL,
[CoresPerSocket] INT NULL,
[TotalCpuCores] INT NULL,
[CpuMhz] INT NULL,
[TotalCpuMhz] INT NULL,
[MemoryTotalGB] DECIMAL(10,2) NULL,
[MemoryUsageGB] DECIMAL(10,2) NULL,
[VMCount] INT NULL,
[EsxiVersion] NVARCHAR(50) NULL,
[EsxiBuild] NVARCHAR(50) NULL,
[UptimeDays] DECIMAL(10,2) NULL
)
MemoryUsageGB reflects real-time memory consumed by running VMs at the time of collection.
UptimeDays will be NULL for hosts that are powered off or disconnected.
#>
[CmdletBinding()]
param(
)
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcro
#region --- Setup ---------------------------------------------------------------
[string] $OutputPath = 'C:\temp\VM_Trends\'
[string] $ServerInstance = 'itdintsql22p1.nd.gov\INTSQL22P1'
[string] $Database = 'ITD-Systems-Automation'
[string] $Table = 'VMware_Trends_Host'
[System.Management.Automation.PSCredential] $SqlCredential = $Secret:sql_itdpsu1
$RunDate = Get-Date
$DateStamp = $RunDate.ToString('yyyyMMdd')
$Timestamp = $RunDate.ToString('yyyy-MM-dd')
if (-not (Test-Path -Path $OutputPath)) {
New-Item -ItemType Directory -Path $OutputPath | Out-Null
}
Start-Transcript -Path (Join-Path $OutputPath "VMHostMetadataReport_$DateStamp.log") -Append
#endregion
#region --- Build VMHost -> Cluster/Datacenter Lookups (avoids per-host queries) -
Write-Verbose 'Building host-to-cluster and host-to-datacenter maps...'
$HostClusterMap = @{}
$HostDatacenterMap = @{}
Get-Datacenter | ForEach-Object {
$DatacenterName = $_.Name
Get-VMHost -Location $_ | ForEach-Object {
$HostDatacenterMap[$_.Name] = $DatacenterName
}
}
Get-Cluster | ForEach-Object {
$ClusterName = $_.Name
Get-VMHost -Location $_ | ForEach-Object {
$HostClusterMap[$_.Name] = $ClusterName
}
}
#endregion
#region --- Collect Host Data --------------------------------------------------
Write-Verbose 'Gathering hosts...'
$AllHosts = $HostDatacenterMap.Keys | ForEach-Object { Get-VMHost -Name $_ }
Write-Verbose "Processing $($AllHosts.Count) hosts..."
$Results = foreach ($VMHost in $AllHosts) {
$Ext = $VMHost.ExtensionData # single API object -- reuse for all fields
#--- CPU info from hardware summary
$CpuSockets = $Ext.Hardware.CpuInfo.NumCpuPackages
$TotalCpuCores = $Ext.Hardware.CpuInfo.NumCpuCores
$CoresPerSocket = if ($CpuSockets -gt 0) { [int]($TotalCpuCores / $CpuSockets) } else { $null }
$CpuMhz = $Ext.Hardware.CpuInfo.Hz / 1000000 # Hz -> MHz
$TotalCpuMhz = $Ext.Summary.Hardware.CpuMhz * $TotalCpuCores
#--- Memory
$MemoryTotalGB = [Math]::Round($VMHost.MemoryTotalGB, 2)
$MemoryUsageGB = [Math]::Round($VMHost.MemoryUsageGB, 2)
#--- VM count on this host right now
$VMCount = ($Ext.Vm | Measure-Object).Count
#--- Uptime (null when host is powered off / disconnected)
$UptimeDays = $null
$BootTime = $Ext.Runtime.BootTime
if ($null -ne $BootTime) {
$UptimeDays = [Math]::Round(($RunDate - $BootTime).TotalDays, 2)
}
[PSCustomObject]@{
ReportDate = $Timestamp
HostName = $VMHost.Name
Datacenter = $HostDatacenterMap[$VMHost.Name]
Cluster = $HostClusterMap[$VMHost.Name]
ConnectionState = $VMHost.ConnectionState
PowerState = $VMHost.PowerState
InMaintenanceMode = $VMHost.ExtensionData.Runtime.InMaintenanceMode
Model = $Ext.Hardware.SystemInfo.Model
ProcessorType = $VMHost.ProcessorType
CpuSockets = $CpuSockets
CoresPerSocket = $CoresPerSocket
TotalCpuCores = $TotalCpuCores
CpuMhz = [int]$CpuMhz
TotalCpuMhz = $TotalCpuMhz
MemoryTotalGB = $MemoryTotalGB
MemoryUsageGB = $MemoryUsageGB
VMCount = $VMCount
EsxiVersion = $VMHost.Version
EsxiBuild = $VMHost.Build
UptimeDays = $UptimeDays
}
}
#endregion
#region --- Export CSV ---------------------------------------------------------
$OutputFile = Join-Path $OutputPath "VMHostMetadata_$DateStamp.csv"
$Results | Export-Csv -Path $OutputFile -NoTypeInformation
Write-Verbose "Exported $($Results.Count) host records to: $OutputFile"
#endregion
#region --- SQL Insert ---------------------------------------------------------
$DataTable = [System.Data.DataTable]::new()
$ColDefs = [ordered]@{
ReportDate = [datetime]
HostName = [string]
Datacenter = [string]
Cluster = [string]
ConnectionState = [string]
PowerState = [string]
InMaintenanceMode = [bool]
Model = [string]
ProcessorType = [string]
CpuSockets = [int]
CoresPerSocket = [int]
TotalCpuCores = [int]
CpuMhz = [int]
TotalCpuMhz = [int]
MemoryTotalGB = [decimal]
MemoryUsageGB = [decimal]
VMCount = [int]
EsxiVersion = [string]
EsxiBuild = [string]
UptimeDays = [decimal]
}
foreach ($Col in $ColDefs.GetEnumerator()) {
$Column = [System.Data.DataColumn]::new($Col.Key, $Col.Value)
$Column.AllowDBNull = $true
[void]$DataTable.Columns.Add($Column)
}
foreach ($Row in $Results) {
$DataRow = $DataTable.NewRow()
foreach ($Col in $ColDefs.Keys) {
$Val = $Row.$Col
$DataRow[$Col] = if ($null -ne $Val) { $Val } else { [DBNull]::Value }
}
[void]$DataTable.Rows.Add($DataRow)
}
$SqlParams = @{
ServerInstance = $ServerInstance
DatabaseName = $Database
SchemaName = 'dbo'
TableName = $Table
Credential = $SqlCredential
InputData = $DataTable
}
Write-SqlTableData @SqlParams
Write-Verbose "Inserted $($DataTable.Rows.Count) host records into [$Database].[dbo].[$Table]"
Disconnect-ITDvCenter
#endregion
#region --- Cleanup -------------------------------------------------------------
Stop-Transcript
#endregion
@@ -0,0 +1,300 @@
<#
.SYNOPSIS
Daily VM metadata report for PowerBI trending and hardware capacity planning.
.DESCRIPTION
Collects VM metadata from vCenter including compute, storage, OS, and VMware Tools
information using only data available within vCenter (no direct guest connections).
Exports a timestamped CSV each run -- append daily runs to build a historical dataset
suitable for PowerBI trend analysis and physical hardware purchasing decisions.
.PARAMETER vCenterServers
One or more vCenter server hostnames. Defaults to itdvmvc1.nd.gov and itdvmvc2.nd.gov.
.PARAMETER DatacenterFilter
Wildcard filter applied to datacenter names. Defaults to 'Primary*'.
.PARAMETER OutputPath
Directory where CSV and log files are written.
Defaults to C:\ITDSCRIPT\Reports\VMMetadata.
.PARAMETER CredentialPath
Path to a saved PSCredential XML file for unattended/scheduled runs.
Create one interactively with:
Get-Credential | Export-Clixml -Path C:\ITDSCRIPT\Creds\vCenter.xml
When omitted the script prompts for credentials.
.EXAMPLE
# Interactive run
.\VMware-VMDailyMetadataReport.ps1
.EXAMPLE
# Scheduled / unattended run
.\VMware-VMDailyMetadataReport.ps1 -CredentialPath 'C:\ITDSCRIPT\Creds\vCenter.xml'
.NOTES
Run the following DDL once to create the destination table:
DROP TABLE IF EXISTS [dbo].[VMware_Trends_VM]
CREATE TABLE [dbo].[VMware_Trends_VM] (
[ReportDate] DATETIME2 NOT NULL,
[VMName] NVARCHAR(255) NOT NULL,
[Datacenter] NVARCHAR(100) NULL,
[Cluster] NVARCHAR(100) NULL,
[PowerState] NVARCHAR(50) NULL,
[IsSRMPlaceholder] BIT NOT NULL,
[StoragePlatform] NVARCHAR(100) NULL,
[GuestOS] NVARCHAR(255) NULL,
[vCPUs] INT NULL,
[MemoryGB] DECIMAL(10,2) NULL,
[ProvisionedSpaceGB] DECIMAL(12,2) NULL,
[UsedSpaceGB] DECIMAL(12,2) NULL,
[GuestDiskCapacityGB] DECIMAL(12,2) NULL,
[GuestDiskUsedGB] DECIMAL(12,2) NULL,
[ToolsRunningStatus] NVARCHAR(100) NULL,
[ToolsVersionStatus] NVARCHAR(100) NULL,
[ToolsVersion] NVARCHAR(50) NULL,
[Tag_DRProtection] NVARCHAR(100) NULL,
[Tag_AppName] NVARCHAR(255) NULL,
[Tag_VRDatastores] NVARCHAR(255) NULL,
[Tag_VRRPO] NVARCHAR(100) NULL,
[Tag_DTAP] NVARCHAR(50) NULL,
[Tag_StartupPriority] NVARCHAR(100) NULL,
[Tag_SRMRecoveryType] NVARCHAR(100) NULL,
[Tag_LicensingRestrictions] NVARCHAR(255) NULL
)
Guest OS disk capacity / used columns are NULL for powered-off VMs and SRM placeholders.
#>
[CmdletBinding()]
param(
)
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcro
#region --- Setup ---------------------------------------------------------------
[string] $OutputPath = 'C:\temp\VM_Trends\'
[string] $ServerInstance = 'itdintsql22p1.nd.gov\INTSQL22P1'
[string] $Database = 'ITD-Systems-Automation'
[string] $Table = 'VMware_Trends_VM'
[System.Management.Automation.PSCredential] $SqlCredential = $Secret:sql_itdpsu1
$RunDate = Get-Date
$DateStamp = $RunDate.ToString('yyyyMMdd')
$Timestamp = $RunDate.ToString('yyyy-MM-dd')
if (-not (Test-Path -Path $OutputPath)) {
New-Item -ItemType Directory -Path $OutputPath | Out-Null
}
Start-Transcript -Path (Join-Path $OutputPath "VMMetadataReport_$DateStamp.log") -Append
#endregion
#region --- Build VMHost -> Cluster/Datacenter Lookups (avoids per-VM API calls) -
Write-Verbose 'Building host-to-cluster and host-to-datacenter maps...'
$HostClusterMap = @{}
$HostDatacenterMap = @{}
Get-Datacenter | ForEach-Object {
$DatacenterName = $_.Name
Get-VMHost -Location $_ | ForEach-Object {
$HostDatacenterMap[$_.Name] = $DatacenterName
}
}
Get-Cluster | ForEach-Object {
$ClusterName = $_.Name
Get-VMHost -Location $_ | ForEach-Object {
$HostClusterMap[$_.Name] = $ClusterName
}
}
#endregion
#region --- Collect VM Data -----------------------------------------------------
Write-Verbose "Gathering VMs"
# Include ALL VMs (SRM placeholders flagged via column, not excluded).
# vCLS agent VMs are excluded -- they are vSphere internal and not customer workloads.
$AllVMs = Get-VM | Where-Object { $_.Name -notlike 'vCLS*' }
#--- Pre-fetch all tag assignments in one API call (avoids per-VM Get-TagAssignment)
Write-Verbose 'Pre-fetching VM tag assignments...'
$TagLookup = @{}
Get-TagAssignment -Entity $AllVMs | ForEach-Object {
$VMId = $_.Entity.Id
$Cat = $_.Tag.Category.Name
$TagName = $_.Tag.Name
if (-not $TagLookup.ContainsKey($VMId)) { $TagLookup[$VMId] = @{} }
if ($TagLookup[$VMId].ContainsKey($Cat)) {
$TagLookup[$VMId][$Cat] += "; $TagName"
} else {
$TagLookup[$VMId][$Cat] = $TagName
}
}
Write-Verbose "Processing $($AllVMs.Count) VMs..."
$Results = foreach ($VM in $AllVMs) {
$Ext = $VM.ExtensionData # single API object -- reuse for all fields
#--- SRM placeholder detection
$IsSRMPlaceholder = $Ext.Summary.Config.ManagedBy.Type -eq 'placeholderVm'
#--- Cluster / Datacenter (null-safe: standalone hosts have no cluster entry)
$ClusterName = $HostClusterMap[$VM.VMHost.Name]
$DatacenterName = $HostDatacenterMap[$VM.VMHost.Name]
#--- Tag assignments (pre-fetched; null when category not assigned to this VM)
$VMTags = if ($TagLookup.ContainsKey($VM.Id)) { $TagLookup[$VM.Id] } else { @{} }
#--- Storage platform parsed from datastore name convention: VMCLUSTER_LUN_PLATFORM_Desc
# Segment 2 = storage platform identifier (e.g. FS92, A9K).
# Cluster grouping uses the compute Cluster column -- no need to re-derive it here.
$StoragePlatforms = foreach ($DSName in $Ext.Config.DatastoreUrl.Name) {
$Segments = $DSName -split '_'
if ($Segments.Count -ge 3) { $Segments[2] }
}
$StoragePlatform = ($StoragePlatforms | Sort-Object -Unique) -join '; '
#--- VMware Tools guest disk info
# Populated only when Tools is running; null otherwise.
$GuestDiskCapacityGB = $null
$GuestDiskUsedGB = $null
if ($Ext.Guest.Disk) {
$TotalCapBytes = ($Ext.Guest.Disk | Measure-Object -Property Capacity -Sum).Sum
$TotalFreeBytes = ($Ext.Guest.Disk | Measure-Object -Property FreeSpace -Sum).Sum
$GuestDiskCapacityGB = [Math]::Round($TotalCapBytes / 1GB, 2)
$GuestDiskUsedGB = [Math]::Round(($TotalCapBytes - $TotalFreeBytes) / 1GB, 2)
}
[PSCustomObject]@{
# --- Identity & grouping
ReportDate = $Timestamp # for PowerBI time-series/trend axis
VMName = $VM.Name
Datacenter = $DatacenterName
Cluster = $ClusterName
PowerState = $VM.PowerState
IsSRMPlaceholder = $IsSRMPlaceholder
StoragePlatform = $StoragePlatform
GuestOS = $Ext.Guest.GuestFullName
# --- Compute
vCPUs = $VM.NumCpu
MemoryGB = $VM.MemoryGB
# --- Datastore-level storage
# ProvisionedSpaceGB : maximum the VM could consume (thin disks counted at max size)
# UsedSpaceGB : bytes actually committed on datastores right now
ProvisionedSpaceGB = [Math]::Round($VM.ProvisionedSpaceGB, 2)
UsedSpaceGB = [Math]::Round($VM.UsedSpaceGB, 2)
# --- Guest OS-level storage (from VMware Tools; null when Tools not running)
# GuestDiskCapacityGB : sum of all volume capacities seen inside the guest
# GuestDiskUsedGB : sum of space consumed across those volumes
GuestDiskCapacityGB = $GuestDiskCapacityGB
GuestDiskUsedGB = $GuestDiskUsedGB
# --- VMware Tools
# ToolsRunningStatus : guestToolsRunning | guestToolsNotRunning | guestToolsExecutingScripts
# ToolsVersionStatus : guestToolsCurrent | guestToolsNeedUpgrade | guestToolsUnmanaged | guestToolsTooNew
# ToolsVersion : numeric build version string reported by vCenter
ToolsRunningStatus = $Ext.Guest.ToolsRunningStatus
ToolsVersionStatus = $Ext.Guest.ToolsVersionStatus
ToolsVersion = $Ext.Guest.ToolsVersion
# --- vCenter Tags
Tag_DRProtection = $VMTags['DR Protection']
Tag_AppName = $VMTags['AppName']
Tag_VRDatastores = $VMTags['VR Datastores']
Tag_VRRPO = $VMTags['VR RPO']
Tag_DTAP = $VMTags['DTAP']
Tag_StartupPriority = $VMTags['StartupPriority']
Tag_SRMRecoveryType = $VMTags['SRM Recovery Type']
Tag_LicensingRestrictions = $VMTags['LicensingRestrictions']
}
}
#endregion
<#region --- Export CSV ---------------------------------------------------------
$OutputFile = Join-Path $OutputPath "VMMetadata_$DateStamp.csv"
$Results | Export-Csv -Path $OutputFile -NoTypeInformation
Write-Verbose "Exported $($Results.Count) VM records to: $OutputFile"
#endregion
#>
#region --- SQL Insert ---------------------------------------------------------
# Build a typed DataTable so Write-SqlTableData knows each column's type
# even when nullable columns contain null values. Type inference from raw
# PSCustomObjects fails when the first row has a null in a numeric column.
$DataTable = [System.Data.DataTable]::new()
$ColDefs = [ordered]@{
ReportDate = [datetime]
VMName = [string]
Datacenter = [string]
Cluster = [string]
PowerState = [string]
IsSRMPlaceholder = [bool]
StoragePlatform = [string]
GuestOS = [string]
vCPUs = [int]
MemoryGB = [decimal]
ProvisionedSpaceGB = [decimal]
UsedSpaceGB = [decimal]
GuestDiskCapacityGB = [decimal]
GuestDiskUsedGB = [decimal]
ToolsRunningStatus = [string]
ToolsVersionStatus = [string]
ToolsVersion = [string]
Tag_DRProtection = [string]
Tag_AppName = [string]
Tag_VRDatastores = [string]
Tag_VRRPO = [string]
Tag_DTAP = [string]
Tag_StartupPriority = [string]
Tag_SRMRecoveryType = [string]
Tag_LicensingRestrictions = [string]
}
foreach ($Col in $ColDefs.GetEnumerator()) {
$Column = [System.Data.DataColumn]::new($Col.Key, $Col.Value)
$Column.AllowDBNull = $true
[void]$DataTable.Columns.Add($Column)
}
foreach ($Row in $Results) {
$DataRow = $DataTable.NewRow()
foreach ($Col in $ColDefs.Keys) {
$Val = $Row.$Col
$DataRow[$Col] = if ($null -ne $Val) { $Val } else { [DBNull]::Value }
}
[void]$DataTable.Rows.Add($DataRow)
}
$SqlParams = @{
ServerInstance = $ServerInstance
DatabaseName = $Database
SchemaName = 'dbo'
TableName = $Table
Credential = $SqlCredential
InputData = $DataTable
}
Write-SqlTableData @SqlParams
Write-Verbose "Inserted $($DataTable.Rows.Count) VM records into [$Database].[dbo].[$Table]"
#endregion
#region --- Cleanup -------------------------------------------------------------
Stop-Transcript
#endregion
@@ -0,0 +1,247 @@
<# NOT FUNCTIONAL YET - WORK IN PROGRESS
.SYNOPSIS
Update/renew any expired iLO certificates in the VMware/Synergy environment
.DESCRIPTION
Update/renew any expired iLO certificates in the VMware/Synergy environment
.NOTES
# retrieve all iLO from Synergy
# find all certificates expiring in the next 3 days, or ones that do not have nd.gov in name, add to an array
# loop through list
## connect to ilo
## generate CSR
## send CSR to sectigo to generate new
## wait for approval
## download new cert
## upload/update/set on iLO
.LINK
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
[CmdletBinding()]
param (
[Parameter(ParameterSetName = 'ByHostName')]
[string[]]
$HostName = $null,
[Parameter(ParameterSetName = 'SynergyDiscovery')]
[switch]
$SynergyDiscovery
)
function Get-SectigoToken {
Write-Verbose -Message "Retrieving Sectigo API key for VMware" -Verbose
$SectigoCred = Get-ITDPassword -Title "Sectigo API key for VMware" -UserName "f595aa76-c26b-4664-b95d-cb805cc7ff4e"
Write-Verbose -Message "Confirming SectigoCred is $($SectigoCred.UserName)" -Verbose
$AuthBody = @{
grant_type = 'client_credentials'
#client_id = $Secret:sectigo_vmware.UserName
#client_secret = $Secret:sectigo_vmware.GetNetworkCredential().Password
client_id = $SectigoCred.UserName
client_secret = $SectigoCred.GetNetworkCredential().Password
}
$AuthBaseAPIUrl = 'https://auth.sso.sectigo.com'
$tokenEndpoint = $AuthBaseAPIUrl + '/auth/realms/apiclients/protocol/openid-connect/token'
$env:SectigoToken = (Invoke-RestMethod -Method Post -Uri $tokenEndpoint -ContentType 'application/x-www-form-urlencoded' -Body $AuthBody).access_token
Return $env:SectigoToken
}
Write-Verbose -Message "Retrieving OneView Service Account credentials" -Verbose
$OVCred = Get-ITDPassword -Title "VMware iLO Service Account" -UserName "ndgov\svcitdvmhpe"
Write-Verbose -Message "Confirming OneView is $($OVCred.UserName)" -Verbose
Import-Module HPEiLOCmdlets -Force
Write-Verbose -Message "Gather PSUniversal Job Information" -Verbose
$PSUJobId = $UAJob.Id
Write-Verbose -Message "Set static variables" -Verbose
$RequesterEmail = 'vmware@nd.gov'
$AppName = "Infra-VMware"
$ServerTypeCode = "Linux"
$Format = "x509CO"
$OrgId = 8133 # Sectigo OrgDept ID for State of North Dakota Information Technology Department - Cloud & Infrastructure
$CertType = 2375 # Sectigo Cert Type for Standard SSL Multi-Domain
$BaseAPIUrl = 'https://admin.hard.sectigo.com'
switch ($PSCmdlet.ParameterSetName) {
'ByHostName' {
$AllILOServers = $HostName
}
'SynergyDiscovery' {
Write-Verbose -Message "Retrieving iLO information from OneView/Synergy" -Verbose
$OneviewServers = @('itdmdnsyncompt1.nd.gov', 'itdmdnsyncompp1.nd.gov', 'itdbissyncompp1.nd.gov')
$AllILOServers = @()
ForEach ($OneviewServer in $OneViewServers ) {
Write-Verbose -Message "Connecting to OneView server $OneviewServer" -Verbose
Connect-OVMgmt -Hostname $OneviewServer -Credential $OVCred -AuthLoginDomain nd.gov -LoginAcknowledge
$AllILOServers += (Get-OVServer).ServerName | ForEach-Object {
$_.split('.')[0] + "lo.nd.gov"
}
Disconnect-OVMgmt
}
}
default {
Write-Error -Message "Invalid parameter set."
exit 1
}
}
Write-Verbose -Message "Checking iLO certificates for expiration or invalid issuer/commonname" -Verbose
$AlliLOToRenew = @()
ForEach ($iLODnsName in $AllILOServers) {
Write-Verbose -Message "Checking certificate for iLO $iLODnsName" -Verbose
$cert = Get-SslCertificate -DNSName $iLODnsName
If ( $cert.NotAfter.AddDays(-7) -le (Get-Date) ) {
Write-Warning -Message "Certificate for $iLODnsName expires on $($cert.NotAfter), add to renewal list."
$AlliLOToRenew += $iLODnsName
}
If ( $cert.subject -notlike "*.nd.gov*") {
Write-Warning -Message "Certificate for $iLODnsName is not a ND.gov cert, add to renewal list."
$AlliLOToRenew += $iLODnsName
}
}
ForEach ($iLOToRenew in $AlliLOToRenew | Select-Object -Unique) {
Write-Verbose -Message "Processing iLO $iLOToRenew for certificate renewal" -Verbose
$iLOCred = $null
switch ($iLOToRenew) {
{ $_ -like "*bis*" } {
Write-Verbose -Message "BIS iLO detected, getting credentials for itdbissyncompp1" -Verbose
$iloCred = Get-ITDPassword -Title "itdbissyncompp1 iLO" -UserName "Administrator";
}
{ $_ -like "*mdn*" } {
Write-Verbose -Message "MDN iLO detected, getting credentials for itdmdnsyncompp1" -Verbose
$iloCred = Get-ITDPassword -Title "itdmdnsyncompp1 iLO" -UserName "Administrator";
}
{ $_ -like "*test*" } {
Write-Verbose -Message "TEST iLO detected, getting credentials for itdmdnsyncompt1" -Verbose
$iloCred = Get-ITDPassword -Title "itdmdnsyncompt1 iLO" -UserName "Administrator";
}
default { Write-Error -Message "No iLO credentials found for $iLOToRenew, skipping."; continue; }
}
try {
Write-Verbose -Message "Establishing connection to iLO $iLOToRenew" -Verbose
$iLOConnection = Connect-HPEiLO -Address $iLOToRenew -Credential $iLOCred -DisableCertificateAuthentication
Write-Verbose -Message "Generating CSR on iLO $iLOToRenew" -Verbose
Start-HPEiLOCertificateSigningRequest -Connection $iLOConnection `
-CommonName $iLOConnection.Hostname `
-Organization "State of North Dakota" `
-Country US `
-City Bismarck `
-State "North Dakota"
Start-Sleep -Seconds 30 ### for some reason if you check iLO for CSR too frequently it doesn't work
Write-Verbose -Message "Getting CSR for $iLOToRenew"
$CsrData = $null
While ($null -eq $CsrData.CertificateSigningRequest) {
try {
$CsrData = Get-HPEiLOCertificateSigningRequest -Connection $iLOConnection
}
catch {
Write-Warning -Message "CSR not ready yet for $iLOToRenew, waiting 10 seconds."
Start-Sleep -Seconds 10
}
}
Disconnect-HPEiLO -Connection $iLOConnection
$iLOConnection = $null
Write-Verbose -Message "Submitting CSR to Sectigo for $iLOToRenew" -Verbose
#Get-SectigoToken ## function above loaded into memory
$EnrollBody = @{
orgId = $OrgId;
certType = $CertType
term = 365;
comments = "iLO Certificate Renewal for $iLOToRenew"
serverType = $ServerTypeCode
csr = $CsrData.CertificateSigningRequest
externalRequester = "vmware@nd.gov"
customFields = @(
@{
name = 'ApplicationName'
value = 'Infra-VMware'
}
)
}
$EnrollParams = @{
Method = 'Post'
Uri = $BaseAPIUrl + "/api/ssl/v1/enroll"
Headers = @{
"Authorization" = ("Bearer " + (Get-SectigoToken))
"Content-Type" = "application/json"
}
Body = ($EnrollBody | ConvertTo-Json -Depth 10)
ContentType = 'application/json'
}
$EnrollResponse = Invoke-RestMethod @EnrollParams
$OrderId = $EnrollResponse.sslId
Write-Verbose -Message "Waiting for certificate issuance for $iLOToRenew" -Verbose
$Certificate = $null
Start-Sleep -Seconds 15
While ($Certificate.status -ne "Issued") {
$ValidateUrl = "${BaseAPIUrl}/api/ssl/v1/${OrderId}"
$ValidateSplat = @{
Uri = $ValidateUrl
Method = 'Get'
Headers = @{
"Authorization" = ("Bearer " + (Get-SectigoToken))
"Content-Type" = "application/json"
}
}
$Certificate = Invoke-RestMethod @ValidateSplat
If ($Certificate.status -ne "Issued") {
Write-Warning -Message "Certificate for $iLOToRenew not issued yet, waiting 15 seconds."
Start-Sleep -Seconds 15
}
}
Write-Verbose -Message "Downloading issued certificate for $iLOToRenew" -Verbose
$CollectUrl = $BaseAPIUrl + "/api/ssl/v1/collect/${OrderId}?format=${Format}"
$CommonName = $Certificate.commonName
$DownloadSplat = @{
Uri = $CollectUrl
Method = 'Get'
Headers = @{
"Authorization" = ("Bearer " + (Get-SectigoToken))
"Content-Type" = "application/json"
}
UseBasicParsing = $true
}
Write-Verbose -Message "Downloading certificate to F:\iLO_certs\$CommonName-$OrderId-$PSUJobId.pem" -Verbose
Invoke-WebRequest @DownloadSplat -OutFile "F:\iLO_certs\$CommonName-$OrderId-$PSUJobId.pem"
Write-Verbose -Message "Importing new certificate to iLO $iLOToRenew" -Verbose
$CertificateToUpload = Get-Content -Path "F:\iLO_certs\$CommonName-$OrderId-$PSUJobId.pem" -Raw
$iLOConnection = Connect-HPEiLO -Address $iLOToRenew -Credential $iLOCred -DisableCertificateAuthentication -Verbose
Import-HPEiLOCertificate -Certificate ($CertificateToUpload | Out-String) -Connection $iLOConnection -Force
Disconnect-HPEiLO -Connection $iLOConnection
Write-Verbose -Message "Disconnecting from iLO $iLOToRenew" -Verbose
}
catch {
}
}
@@ -0,0 +1,133 @@
<#####
.SYNOPSIS
Creates a vCenter scheduled task that will create a virtual machine snapshot.
.DESCRIPTION
Creates a vCenter scheduled task that will create a virtual machine snapshot.
.NOTES
.LINK
https://northdakota.service-now.com/kb_view.do?sysparm_article=KB0017146
#>
[CmdletBinding()]
param (
[Parameter(
Mandatory = $true,
HelpMessage = "The VMware virtual machine name. This is most commonly the FQDN. You can verify the virtual machine name by logging into vCenter. Multiple entries can be submitted if the field loses focus, and you go back to it. For example, after each entry hit Tab, then Shift-Tab back."
)]
[string[]]
$VMName = $null,
[Parameter(Mandatory = $true,
HelpMessage = "The DateTime you want the snapshot to occur.")]
[datetime]
$DateTime = (Get-Date),
[Parameter(Mandatory = $true,
HelpMessage = "How many hours the snapshot will exist. The snapshot will be automatically deleted after the duration. Maximum value is 72 hours.")]
[ValidateRange(1, 72)]
[int]
$DurationHours = 4,
[Parameter(HelpMessage = "Email address that you want vCenter to notify when the snapshot is taken. Multiple entries can be submitted if the field loses focus, and you go back to it. For example, after each entry hit Tab, then Shift-Tab back.")]
[string[]]
$Email = $null
)
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$StartDateTime = $DateTime
$EndDateTime = $StartDateTime.AddHours($DurationHours)
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
$StartDateTimeSql = $StartDateTime.ToString('yyyy/MM/dd HH:mm:ss')
$EndDateTimeSql = $EndDateTime.ToString('yyyy/MM/dd HH:mm:ss')
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "After Connect vCenter" -Verbose
ForEach ($name in $VMName) {
Write-Verbose -Message ("Add record to SQL") -Verbose
$SqlQuery = "INSERT INTO [$SnapshotTable] (VMName, DateTime, RequestedBy, DurationHours,Status,ExpireDateTime,NotifyEmail,PSUJobIdRequest) Values ('$Name', '$StartDateTimeSql', '$RequestedBy', $DurationHours, 'Requested', '$EndDateTimeSql','$Email','$PSUJobId');SELECT SCOPE_IDENTITY();"
Write-Verbose -Message $SqlQuery -Verbose
$SnapshotId = (Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose).Column1
Write-Verbose -Message ("Snapshot ID is $SnapshotId") -Verbose
Write-Verbose -Message "Get SQL record" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE ID='$SnapshotId'"
Write-Verbose -Message $SqlQuery -Verbose
$SqlRecord = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message $SqlRecord -Verbose
Write-Verbose -Message ("Determine description metadata") -Verbose
$MetadataObj = @{
Id = [int]$SnapshotId;
Taken = $StartDateTime;
Expire = $EndDateTime;
RequestedBy = $RequestedBy;
DurationHours = $DurationHours;
PSUJobIdRequest = $PSUJobId;
}
Write-Verbose -Message ("Create VM Scheduled Task for Snapshot " + $SnapshotId) -Verbose
$NewITDVMwareVMSnapshotTaskParams = @{
VMName = $name;
Name = ("AutoSnap_" + $SnapshotId)
Description = $MetadataObj | ConvertTo-Json
DateTime = $StartDateTime;
}
switch ($PSBoundParameters.Keys) {
Email {
$NewITDVMwareVMSnapshotTaskParams.Email = $Email
}
}
try {
New-ITDVMwareVMSnapshotTaskV3 @NewITDVMwareVMSnapshotTaskParams -Verbose -ErrorAction Stop
Write-Verbose -Message ("Setting SQL status to Scheduled") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Scheduled' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message ($NewITDVMwareVMSnapshotTaskParams.Name + " has been scheduled.") -Verbose
}
catch {
Write-Verbose -Message "ObjectNotFound Error" -Verbose
switch ($Error[0].Exception.ErrorCategory) {
'ObjectNotFound' {
# update SQL with error
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed, ObjectNotFound.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-VMNotFound' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
'Default' {
# update SQL with error
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-GenericError' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Write-Error -Message $Error[0]
}
}
Disconnect-ITDvCenter
# Write-Verbose -Message ("If scheduled task is created successfully, create SNow CHG for this, using scheduled StartDateTime... work TBD") -Verbose
@@ -0,0 +1,99 @@
[CmdletBinding()]
param (
[string]
$VMName,
[int]
$Id,
[switch]
$WhatIf
)
$PSUJobId = $UAJob.Id
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
# find all VMs, with VMName if entered
If ($PSBoundParameters.ContainsKey('VMName')) {
Write-Verbose -Message "VMName parameter found $VMName" -Verbose
$VMs = Get-VM -Name $VMName | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
}
Else {
$VMs = Get-VM | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
}
# find expired snapshots of the VMs
If ($PSBoundParameters.ContainsKey('Id')) {
Write-Verbose -Message "ID parameter found $Id" -Verbose
$AllSnapshots = $VMs | Get-Snapshot | Where-Object Name -EQ "AutoSnap_$Id"
}
Else {
$AllSnapshots = $VMs | Get-Snapshot | Where-Object Name -Like "AutoSnap_2*" ##### Remove the '2' after SharePoint snapshots are all deleted
}
ForEach ($Snapshot in $AllSnapshots) {
Write-Verbose -Message ("Start Snapshot " + $Snapshot.Description) -Verbose
$SnapshotObj = $null
$SnapshotObj = $Snapshot.Description | ConvertFrom-Json
If ($null -ne $SnapshotObj -and $SnapshotObj.Expire -lt (Get-Date)) {
# remove snapshot if expired
If ($WhatIf) {
Write-Verbose -Message ("What if: Performing the operation Remove-Snapshot on Snapshot " + $Snapshot.Name) -Verbose
}
Else {
Write-Verbose -Message ("VMName: " + $Snapshot.VM.Name + " / Snapshot ID: " + $SnapshotObj.Id + " -- attempting removal") -Verbose
# update SQL status to "Delete-Attempted"
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Delete-AutoAttempt', PSUJobIdDelete = '$PSUJobId' WHERE ID = " + $Snapshot.Name.split('_')[1])
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
# Remove Snapshot
$Snapshot | Remove-Snapshot -Confirm:$false -Verbose
# confirm snapshot is truly gone, then update sql with results
If (Get-VM -Name $Snapshot.VM.Name | Get-Snapshot -Id $SnapshotObj.Id -ErrorAction SilentlyContinue) {
$RemoveStatus = $false
}
Else {
# snapshot does not exist
$RemoveStatus = $true
}
# update SQL
switch ($RemoveStatus) {
$true {
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-AutoSuccess' WHERE ID = " + $Snapshot.Name.split('_')[1])
}
$false {
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-AutoFailure' WHERE ID = " + $Snapshot.Name.split('_')[1])
}
}
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Else {
# do nothing
Write-Verbose -Message ("VMName: " + $Snapshot.VM.Name + " / Snapshot ID: " + $SnapshotObj.Id + " has not expired.") -Verbose
}
}
Disconnect-ITDvCenter
@@ -0,0 +1,203 @@
[CmdletBinding()]
param (
[int]
$Id
)
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
switch($UAJob.ComputerName){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
# get list of All vCenter Scheduled Tasks
$si = Get-View ServiceInstance
$scheduledTaskManager = Get-View $Si.Content.ScheduledTaskManager
Write-Verbose -Message ("Gathering all scheduled tasks with AutoSnap in the task name, this will take some time")
$AllScheduledTasks = Get-View -Id $scheduledTaskManager.ScheduledTask | Where-Object { $_.Info.Name -like "AutoSnap*" }
Write-Verbose -Message "Get SQL records with status of Scheduled" -Verbose
# get list of Scheduled from database
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Scheduled'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Scheduled status") -Verbose
Write-Verbose -Message "Start Scheduled > Taken Loops"
ForEach ($SqlRecord in @($SqlRecords) ) {
$Snapshot = $null
Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
$Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
If ($Snapshot) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
Write-Verbose -Message ("Setting SQL status to Taken") -Verbose
# if status has changed from requested to taken, update database status field
$TakenDateTimeSql = ($Snapshot.Description | ConvertFrom-Json).Taken.ToString('yyyy/MM/dd HH:mm:ss')
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Taken', TakenDateTime = '" + $TakenDateTimeSql + "' WHERE ID = " + $Snapshot.Name.split('_')[1])
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Else {
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
If ($SqlRecord.DateTime -lt (Get-Date)) {
Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " not found, and its requested datetime has passed") -Verbose
# Update SQL record to status Failed-ScheduledNotTaken
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-ScheduledNotTaken' WHERE ID = " + $SqlRecord.Id)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose
}
Write-Verbose -Message "End Scheduled > Taken Loops"
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
# get list of taken from database
Write-Verbose -Message "Start Taken > Expire Loops"
Write-Verbose -Message "Get SQL records with status of Taken" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Taken'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
# check status of all Taken SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Taken status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
$Snapshot = $null
Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
$Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
If ($Snapshot) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
# if expired datetime is in the past, set status to expired
If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has expired.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1])
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Else {
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
}
# get list of Expired from SQL database
Write-Verbose -Message "Start Expired > Removed Loops"
Write-Verbose -Message "Get SQL records with status of Expired" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Expired'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
# check status of all Expired SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Expired status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
$Snapshot = $null
Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
$Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
If ($Snapshot) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
# if expired datetime is in the past, set status to expired
If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) {
Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " is expired. Will be removed at next Removal run") -Verbose
#$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1])
#Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
}
Else {
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
}
# get list of requested from SQL database
Write-Verbose -Message "Start Requested > Scheduled Loops"
Write-Verbose -Message "Get SQL records with status of Requested" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Requested'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
switch ($PSBoundParameters.Keys) {
Id {
Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
$SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
}
}
# check status of all Requested SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Requested status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
# does the scheduled tasks exist?
If ($AllScheduledTasks | Where-Object { $_.Info.Name -eq ("AutoSnap_" + $SqlRecord.Id + '_' + $SqlRecord.VMName) }) {
# yes - update SQL status to Scheduled
Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " vCenter scheduled task exists.") -Verbose
Write-Verbose -Message ("Setting SQL status to Scheduled") -Verbose
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Scheduled' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Else {
# no
# has date/time passed? (10 minute buffer)
If ($SqlRecord.DateTime -lt (Get-Date).AddMinutes(-10)) {
# yes - set SQL status to Failed-RequestedNotScheduled
Write-Warning -Message ("AutoSnap_" + $SqlRecord.Id + " was not scheduled before its datetime.")
$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-RequestedNotScheduled' WHERE ID = " + $SqlRecord.ID)
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
}
Else {
# no ???
}
Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " scheduled task does not exist.")
}
}
Write-Verbose -Message "End Requested > Scheduled Loops"
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null
Disconnect-ITDvCenter
@@ -0,0 +1,90 @@
Param(
[string]
$Ritm,
[string]
$ComputerName
)
# $cat_item_sys_id = 'c64e27af47244610b7853238436d435d'
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
Write-Verbose -Message "Prep variable and SQL connection" -Verbose
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "ServiceNow_RitmDump_ServerBuildRequestV1"
$AllRitms = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $Ritm -IncludeCustomVariable -IncludeVariableSet
ForEach ($Ritm in $AllRitms) {
Write-Verbose ("Start " + $Ritm.number) -Verbose
# get all variable set rows
$VariableSet = (Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $Ritm.number.value -IncludeVariableSet).VariableSet
ForEach ($VSet in $VariableSet) {
Write-Verbose -Message ("Start " + $VSet.host_name + ' *** ' + $VSet.host_name_ref)
# figure out values
$RitmNum = $Ritm.number.value
$RitmSysId = $Ritm.sys_id.value
$opened_at = $Ritm.opened_at.display_value
$requested_for = $Ritm.requested_for.display_value
$request_type = $Ritm.CustomVariable.request_type.value
$environment = $Ritm.CustomVariable.environment.value
$host_name_ref = $VSet.host_name_ref
$host_name = If ($VSet.host_name_ref) {
(Get-ITDServiceNowRecord -Table cmdb_ci -SysId $VSet.host_name_ref).Name.display_value
}
Else {
$VSet.host_name
}
$server_type = $VSet.server_type
$operating_system = $VSet.operating_system
$target_os_version_linux = $VSet.target_os_version_linux
$target_os_version_windows = $VSet.target_os_version_windows
$target_platform = $VSet.target_platform
$processors = $VSet.processors
$memory_gb = $VSet.memory_gb
$cidr_block_sys_id = $VSet.cidr_block
$cidr_block = (Get-ITDServiceNowRecord -Table 'cmdb_ci_ip_network' -SysId $cidr_block_sys_id).subnet.display_value
$vlan_id = $VSet.vlan_id
$data_center = $VSet.data_center
$licensing_restrictions = $VSet.licensing_restrictions
$application_info_sys_id = $VSet.application_info
$application_info = (Get-ITDServiceNowRecord -Table 'cmdb_ci_service' -SysId $application_info_sys_id).name.display_value
$support_hours = $VSet.support_hours
$dr_protection = $VSet.dr_protection
$startup_priority = $VSet.startup_priority
$disk_1_os = $VSet.disk_1_os
$disk_2_swap_disk = $VSet.disk_2_swap_disk
$disk_3 = $VSet.disk_3
$disk_4 = $VSet.disk_4
$disk_5 = $VSet.disk_5
$disk_6 = $VSet.disk_6
$disk_7 = $VSet.disk_7
$disk_8 = $VSet.disk_8
$disk_9 = $VSet.disk_9
$disk_10 = $VSet.disk_10
$disk_11 = $VSet.disk_11
$disk_12 = $VSet.disk_12
$disk_13 = $VSet.disk_13
$disk_14 = $VSet.disk_14
$disk_15 = $VSet.disk_15
$disk_16 = $VSet.disk_16
$special_instructions = $Ritm.CustomVariable.special_instructions.value
$customer_request = $Ritm.CustomVariable.customer_request.value
$additional_comments = $Ritm.CustomVariable.additional_comments.value
If ($host_name -eq $ComputerName) {
Write-Verbose -Message ("Add to SQL " + $VSet.host_name + ' *** ' + $VSet.host_name_ref)
# add record to SQL
$SqlQuery = "INSERT INTO [$Table] (
RitmNum, RitmSysId, opened_at,requested_for,request_type,environment,host_name_ref,host_name,server_type,operating_system,target_os_version_linux,target_os_version_windows,target_platform,processors,memory_gb,cidr_block_sys_id,cidr_block,vlan_id,data_center,licensing_restrictions,application_info_sys_id,application_info,support_hours,dr_protection,startup_priority,disk_1_os,disk_2_swap_disk,disk_3,disk_4,disk_5,disk_6,disk_7,disk_8,disk_9,disk_10,disk_11,disk_12,disk_13,disk_14,disk_15,disk_16,special_instructions,customer_request,additional_comments) Values (
'$RitmNum','$RitmSysId','$opened_at','$requested_for','$request_type','$environment','$host_name_ref','$host_name','$server_type','$operating_system','$target_os_version_linux','$target_os_version_windows','$target_platform','$processors','$memory_gb','$cidr_block_sys_id','$cidr_block','$vlan_id','$data_center','$licensing_restrictions','$application_info_sys_id','$application_info','$support_hours','$dr_protection','$startup_priority','$disk_1_os','$disk_2_swap_disk','$disk_3','$disk_4','$disk_5','$disk_6','$disk_7','$disk_8','$disk_9','$disk_10','$disk_11','$disk_12','$disk_13','$disk_14','$disk_15','$disk_16','$special_instructions','$customer_request','$additional_comments'
)
"
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message $SqlQuery -Verbose
}
Write-Verbose -Message ("End " + $VSet.host_name + ' *** ' + $VSet.host_name_ref)
}
Write-Verbose ("End " + $Ritm.number) -Verbose
}
@@ -0,0 +1,46 @@
Param(
[Parameter(Mandatory = $true, ParameterSetName = 'VMName')]
[string[]]
$VMName,
[Parameter(Mandatory = $true, ParameterSetName = 'NewBuilds')]
[switch]
$NewBuilds,
[Parameter(Mandatory = $true, ParameterSetName = 'All')]
[switch]
$All
)
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcauto
switch ($PSCmdlet.ParameterSetName) {
'VMName' {
Write-Verbose -Message "Parameter Set VMName" -Verbose
$VMs = Get-VM -Name $VMName
}
'NewBuilds' {
Write-Verbose -Message "Parameter Set NewBuilds" -Verbose
$VMs = Get-Folder -Name "_New Builds" | Get-VM
}
'All' {
Write-Verbose -Message "Parameter Set All" -Verbose
$VMs = Get-VM | Where-Object CreateDate -lt ((Get-Date).AddDays(-2))
}
}
ForEach($VM in $VMs){
try{
Write-Verbose -Message ("Start " + $VM.Name) -Verbose
Get-VM -Name $VM.Name | Select Uid
Move-ITDVMwareVMToAppNameFolder -VMName $VM.Name -ErrorAction Stop -Verbose
}
catch {
$error[0]
}
}
Write-Verbose -Message "Disconnect from vCenter" -Verbose
Disconnect-ITDvCenter
@@ -0,0 +1,58 @@
Param(
[Parameter(Mandatory = $true, ParameterSetName = 'VMName')]
[string[]]
$VMName,
[Parameter(Mandatory = $true, ParameterSetName = 'NewBuilds')]
[switch]
$NewBuilds,
[Parameter(Mandatory = $true, ParameterSetName = 'All')]
[switch]
$All
)
Write-Verbose -Message "Connect to ServiceNow" -Verbose
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcauto
<#switch ($PSBoundParameters.ContainsKey('VMName')) {
$true {
$VMs = Get-VM -Name $VMName
}
$false {
Write-Verbose -Message "VMName parameter not provided, working on new builds only" -Verbose
$VMs = Get-Folder -Name "_New Builds" | Get-VM | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
}
}#>
switch ($PSCmdlet.ParameterSetName) {
'VMName' {
Write-Verbose -Message "Parameter Set VMName" -Verbose
$VMs = Get-VM -Name $VMName
}
'NewBuilds' {
Write-Verbose -Message "Parameter Set NewBuilds" -Verbose
$VMs = Get-Folder -Name "_New Builds" | Get-VM
}
'All' {
Write-Verbose -Message "Parameter Set All" -Verbose
$VMs = Get-VM
}
}
ForEach($VM in $VMs){
try{
Write-Verbose -Message ("Start " + $VM.Name) -Verbose
Set-ITDVMwareVMTagFromCmdb -VMName $VM.Name -ErrorAction Stop -Verbose
}
catch {
$error[0]
}
}
Write-Verbose -Message "Disconnect from vCenter" -Verbose
Disconnect-ITDvCenter
@@ -0,0 +1,158 @@
# loop through them, create sql record
# $cat_item_sys_id = 'c64e27af47244610b7853238436d435d'
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
Write-Verbose -Message "Prep variable and SQL connection" -Verbose
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "ServiceNow_RitmDump_ServerBuildRequestV1"
# get most recent RITM from SQL, get the opened_at value
$SqlQuery = "SELECT [RitmNum],[RitmSysId],[opened_at] FROM [$Database].[dbo].[$Table]"
$SqlExistingRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
$NewestRecord = ($SqlExistingRecords | Sort-Object -Descending opened_at) | select -First 1
$DateYMDFilter = ($NewestRecord.opened_at | Get-Date -UFormat "%Y-%m-%d")
$DateHMSFilter = ($NewestRecord.opened_at | Get-Date -UFormat "%H:%M:%S")
#$Filter = "cat_item=c64e27af47244610b7853238436d435d^opened_at>javascript:gs.dateGenerate('2024-07-30','23:59:59')"
#$Filter = "cat_item=c64e27af47244610b7853238436d435d"
$Filter = "cat_item=c64e27af47244610b7853238436d435d^opened_at>javascript:gs.dateGenerate('$DateYMDFilter','$DateHMSFilter')"
Write-Verbose -Message ("Filter is " + $Filter) -Verbose
# retrieve list of RITMs created since $opened_at (>opened_at)
Write-Verbose -Message "Retrieve list of RITMs created since last update" -Verbose
#$AllRitms = Get-ITDServiceNowRecord -ItemType 'Request Item' -Filter $Filter -IncludeTotalCount -IncludeCustomVariable | Sort-Object Number
$AllRitms = Get-ITDServiceNowRecord -ItemType 'Request Item' -Filter $Filter -IncludeTotalCount -IncludeCustomVariable | Sort-Object Number
#$AllRitms = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number 'RITM0262097' -IncludeCustomVariable
Write-Verbose -Message ("RITMs found: " + @($AllRitms).count) -Verbose
ForEach ($Ritm in $AllRitms) {
Write-Verbose ("Start " + $Ritm.number) -Verbose
# get all variable set rows
$VariableSet = (Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $Ritm.number.value -IncludeVariableSet).VariableSet
ForEach ($VSet in $VariableSet) {
Write-Verbose -Message ("Start " + $VSet.host_name + ' *** ' + $VSet.host_name_ref)
# figure out values
$RitmNum = $Ritm.number.value
$RitmSysId = $Ritm.sys_id.value
$opened_at = $Ritm.opened_at.display_value
$requested_for = $Ritm.requested_for.display_value
$request_type = $Ritm.CustomVariable.request_type.value
$environment = $Ritm.CustomVariable.environment.value
$host_name_ref = $VSet.host_name_ref
$host_name = If ($VSet.host_name_ref) {
(Get-ITDServiceNowRecord -Table cmdb_ci -SysId $VSet.host_name_ref).Name.display_value
}
Else {
$VSet.host_name
}
$server_type = $VSet.server_type
$operating_system = $VSet.operating_system
$target_os_version_linux = $VSet.target_os_version_linux
$target_os_version_windows = $VSet.target_os_version_windows
$target_platform = $VSet.target_platform
$processors = $VSet.processors
$memory_gb = $VSet.memory_gb
$cidr_block_sys_id = $VSet.cidr_block
$cidr_block = (Get-ITDServiceNowRecord -Table 'cmdb_ci_ip_network' -SysId $cidr_block_sys_id).subnet.display_value
$vlan_id = $VSet.vlan_id
$data_center = $VSet.data_center
$licensing_restrictions = $VSet.licensing_restrictions
$application_info_sys_id = $VSet.application_info
$application_info = (Get-ITDServiceNowRecord -Table 'cmdb_ci_service' -SysId $application_info_sys_id).name.display_value
$support_hours = $VSet.support_hours
$dr_protection = $VSet.dr_protection
$startup_priority = $VSet.startup_priority
$disk_1_os = $VSet.disk_1_os
$disk_2_swap_disk = $VSet.disk_2_swap_disk
$disk_3 = $VSet.disk_3
$disk_4 = $VSet.disk_4
$disk_5 = $VSet.disk_5
$disk_6 = $VSet.disk_6
$disk_7 = $VSet.disk_7
$disk_8 = $VSet.disk_8
$disk_9 = $VSet.disk_9
$disk_10 = $VSet.disk_10
$disk_11 = $VSet.disk_11
$disk_12 = $VSet.disk_12
$disk_13 = $VSet.disk_13
$disk_14 = $VSet.disk_14
$disk_15 = $VSet.disk_15
$disk_16 = $VSet.disk_16
$special_instructions = $Ritm.CustomVariable.special_instructions.value
$customer_request = $Ritm.CustomVariable.customer_request.value
$additional_comments = $Ritm.CustomVariable.additional_comments.value
Write-Verbose -Message ("Add to SQL " + $VSet.host_name + ' *** ' + $VSet.host_name_ref)
# add record to SQL
$SqlQuery = "INSERT INTO [$Table] (
RitmNum, RitmSysId, opened_at,requested_for,request_type,environment,host_name_ref,host_name,server_type,operating_system,target_os_version_linux,target_os_version_windows,target_platform,processors,memory_gb,cidr_block_sys_id,cidr_block,vlan_id,data_center,licensing_restrictions,application_info_sys_id,application_info,support_hours,dr_protection,startup_priority,disk_1_os,disk_2_swap_disk,disk_3,disk_4,disk_5,disk_6,disk_7,disk_8,disk_9,disk_10,disk_11,disk_12,disk_13,disk_14,disk_15,disk_16,special_instructions,customer_request,additional_comments) Values (
'$RitmNum','$RitmSysId','$opened_at','$requested_for','$request_type','$environment','$host_name_ref','$host_name','$server_type','$operating_system','$target_os_version_linux','$target_os_version_windows','$target_platform','$processors','$memory_gb','$cidr_block_sys_id','$cidr_block','$vlan_id','$data_center','$licensing_restrictions','$application_info_sys_id','$application_info','$support_hours','$dr_protection','$startup_priority','$disk_1_os','$disk_2_swap_disk','$disk_3','$disk_4','$disk_5','$disk_6','$disk_7','$disk_8','$disk_9','$disk_10','$disk_11','$disk_12','$disk_13','$disk_14','$disk_15','$disk_16','$special_instructions','$customer_request','$additional_comments'
)
"
Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
Write-Verbose -Message ("End " + $VSet.host_name + ' *** ' + $VSet.host_name_ref)
}
Write-Verbose ("End " + $Ritm.number) -Verbose
}
<# scratch
Write-Verbose -Message ("Add record to SQL") -Verbose
$SqlQuery = "INSERT INTO [$SnapshotTable] (VMName, DateTime, RequestedBy, DurationHours,Status,ExpireDateTime,NotifyEmail,PSUJobIdRequest) Values ('$Name', '$StartDateTimeSql', '$RequestedBy', $DurationHours, 'Requested', '$EndDateTimeSql','$Email','$PSUJobId');SELECT SCOPE_IDENTITY();"
#Write-Verbose -Message $SqlQuery -Verbose
$SnapshotId = (Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:itdpsu1 -Verbose).Column1
select TOP (1000) [RitmNum]
, [RitmSysId]
, [opened_at]
, [requested_for]
, [request_type]
, [environment]
, [host_name_ref]
, [host_name]
, [server_type]
, [operating_system]
, [target_os_version_linux]
, [target_os_version_windows]
, [target_platform]
, [processors]
, [memory_gb]
, [cidr_block_sys_id]
, [cidr_block]
, [vlan_id]
, [data_center]
, [licensing_restrictions]
, [application_info_sys_id]
, [application_info]
, [support_hours]
, [dr_protection]
, [startup_priority]
, [disk_1_os]
, [disk_2_swap_disk]
, [disk_3]
, [disk_4]
, [disk_5]
, [disk_6]
, [disk_7]
, [disk_8]
, [disk_9]
, [disk_10]
, [disk_11]
, [disk_12]
, [disk_13]
, [disk_14]
, [disk_15]
, [disk_16]
, [special_instructions]
, [customer_request]
, [additional_comments]
FROM [ITD-Systems-Automation].[dbo].[ServiceNow_RitmDump_ServerBuildRequestV1]
#>
@@ -0,0 +1,25 @@
Param(
[string]
$VMName,
[switch]
$SRMImplemented
)
Write-Verbose "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcro
Write-Verbose "Start Sync" -Verbose
switch ($PSBoundParameters.Keys){
'VMName' { $SyncITDVMwareVMMetadataToSharePointParams += @{VMName = $VMName} }
'SRMImplemented' { $SyncITDVMwareVMMetadataToSharePointParams += @{SRMImplemented = $SRMImplemented} }
}
Write-Host $SyncITDVMwareVMMetadataToSharePointParams
Sync-ITDVMwareVMMetadataToSharePoint @SyncITDVMwareVMMetadataToSharePointParams -Verbose
#Write-Output $VMName
Write-Verbose "End Sync"
Write-Verbose "Disconnect vCenter"
Disconnect-ITDvCenter
@@ -0,0 +1,10 @@
Write-Verbose -Message "Connect to ServiceNow" -Verbose
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmvcauto
Write-Verbose -Message "Execute Sync-ITDVMareVMTagsFromCmdb" -Verbose
Sync-ITDVMwareVMTagsFromCmdb -Verbose
Disconnect-ITDvCenter
@@ -0,0 +1,2 @@
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
Update-ITDSNowVMTaskDescription -Verbose
@@ -0,0 +1,21 @@
<#Param(
[string]
$SCTaskNum = "World"
)
Write-Host "Hello, $WorldName!"#>
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdiaasauto -Verbose
$NewVMParams = @{
Name = "itdzmtest"+(100..999 | Get-Random) + ".nd.gov"
ResourcePool = "WINDOWS1"
Datastore = "WINDOWS1_FS92_Gen";
DiskStorageFormat = "Thin";
Template = "Windows Server 2022 Standard 2108.21";
Location = Get-Cluster "WINDOWS1" | Get-Datacenter | Get-Folder -Name "_New Builds"
}
New-VM @NewVMParams
Disconnect-ITDvCenter
@@ -0,0 +1,152 @@
<#
.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 | Sort-Object Number | Select-Object -First 3
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]
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 "Get-HelloWorld.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
#Invoke-PSUScript -Script "New-ITDWindowsVmAzure_Step2.ps1" -SCTaskNum $SCTaskNum
}
'vmware' {
$target_platform = "VMware"
Write-Verbose "Invoking PSUScript for VMware Step 2" -Verbose
$PSUJob = Invoke-PSUScript -Script "Get-HelloWorld.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 "Get-HelloWorld.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 "Get-HelloWorld.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 }
}
}
#>
#Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot02.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot03.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot04.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot05.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot06.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot07.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot08.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot09.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot10.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot11.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot12.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot13.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot14.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
Invoke-PSUScript -Name New-ITDWindowsVmAzure_Step1.ps1 -FQDN itdcopilot15.testnd.gov -DiskOsGB 128 -Subnet 10.21.29.96/27 -OS "Windows 11 24H2" -VMEnvironment 'Test' -AppName ITD-POC-Copilot -LicensingRestrictions "No Licensing Restrictions" -DiskDataGB 0 -VMSizeOverride "Standard_D4ds_v5"
@@ -0,0 +1,6 @@
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
@@ -0,0 +1,77 @@
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 | 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) {
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 "Get-HelloWorld.ps1" -SCTaskNum $SCTaskNum
$WorkNotesMsg = ("VMware build Step 1 started.`nPSU Job Id #" + $PSUJob.Id)
}
}
Break
}
}
}
catch {
Write-Error -Message $error[0]
}
Write-Verbose -Message "End $SCTaskNum" -Verbose
}
@@ -0,0 +1,11 @@
# It all starts with a single line of powershell code.
Write-Warning -Message ("Secret direct: " + $Secret:ndgov_svcitdvmhpe.username)
$vaultcred = Get-ITDPassword -Title "IaaS Automation Account" -UserName "ndgov\svcitdiaasauto"
Write-Warning -Message ("Secret vault: " + $vaultcred.username)
$vaultcred2 = Get-ITDPassword -Title "VMware iLO Service Account" -UserName "ndgov\svcitdvmhpe"
Write-Warning -Message ("Secret vault: " + $vaultcred2.username)
@@ -0,0 +1,5 @@
$x=Invoke-PSUScript -Name Get-HelloWorld.ps1 -WorldName "zm"
Write-Warning $x.Id
$x=Invoke-PSUScript -Name Get-HelloWorld.ps1 -WorldName "zo"
Write-Warning $x.Id
@@ -0,0 +1,2 @@
# It all starts with a single line of powershell code.
Write-Verbose -Message $Secret:ndgov_svcitdpsuwin.username -Verbose
@@ -0,0 +1,16 @@
param (
# [Parameter(Mandatory = $true,
# HelpMessage = "CRC TEXT ONLY")]
# [string]
# $CSR,
[Parameter(Mandatory = $true,
HelpMessage = "CRC File")]
[file]
$CSRfile
)
#$csr=Get-Content -raw $Csrfile
$csr = [Text.Encoding]::UTF8.GetString($CSRfile.Content)
Write-Host $csr
@@ -0,0 +1,16 @@
Param(
[ValidateScript( {$_ -in @($zmtest) } )]
[string]
$variable1,
[ValidateSet( '1000','1001','1002','1003','1004','1005','1006','1007','1008','1009','1010','1011','1012','1013','1014','1015','1016','1017','1018','1019','1020','1021','1022','1023','1024','1025','1026','1027','1028','1029','1030','1031','1032','1033','1034','1035','1036','1037','1038','1039','1040','1041','1042','1043','1044','1045','1046','1047','1048','1049','1050','1051','1052','1053','1054','1055','1056','1057','1058','1059','1060','1061','1062','1063','1064','1065','1066','1067','1068','1069','1070','1071','1072','1073','1074','1075','1076','1077','1078','1079','1080','1081','1082','1083','1084','1085','1086','1087','1088','1089','1090','1091','1092','1093','1094','1095','1096','1097','1098','1099','1100'
) ]
[string]
$variable2
)
write-warning $variable1
write-host $variable2
@@ -0,0 +1,18 @@
switch ($env:computername) {
"ITDWINAUTOT1" {
New-UDTypography -Text 'NPD'
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "Infra_WindowsServer_FileManagement_RemoveITDExpiredFiles_PRD"
}
"ITDWINAUTOP1" {
New-UDTypography -Text 'PRD'
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "Infra_WindowsServer_FileManagement_RemoveITDExpiredFiles_PRD"
}
}
$SqlQuery = "SELECT [PSUJobId],[DateTime],[ComputerName],[Status],[FullName] FROM [$Database].[dbo].[$Table]"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
@@ -0,0 +1,25 @@
$Navigation = @(
New-UDListItem -Label 'Home' -OnClick {
Invoke-UDRedirect -Url '/Home'
}
switch($env:computername){
"ITDWINAUTOT1" {
New-UDListItem -Label 'Remove-ITDExpiredFiles Log' -OnClick {
Invoke-UDRedirect -Url '/NPD'
}
}
"ITDWINAUTOP1" {
New-UDListItem -Label 'Remove-ITDExpiredFiles Log' -OnClick {
Invoke-UDRedirect -Url '/PRD'
}
}
}
)
New-UDApp -Title 'PowerShell Universal' -Pages @(
Get-UDPage -Name 'Home'
switch($env:computername){
"ITDWINAUTOT1" { Get-UDPage -Name 'NPD' }
"ITDWINAUTOP1" { Get-UDPage -Name 'PRD' }
}
) -Navigation $Navigation
@@ -0,0 +1,30 @@
New-UDPage -Url "/PRD" -Name "PRD" -Content {
New-UDTypography -Text 'Remove Expired Files Log'
switch($env:COMPUTERNAME){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "Infra_WindowsServer_FileManagement_RemoveITDExpiredFiles_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = "Infra_WindowsServer_FileManagement_RemoveITDExpiredFiles_PRD"
}
}
$SqlQuery = "SELECT [PSUJobId],[DateTime],[ComputerName],[Status],[FullName] FROM [$Database].[dbo].[$Table]"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
New-UDTable -Columns @(
New-UDTableColumn -Property 'PSUJobId' -Title 'PSUJobId' -ShowFilter
New-UDTableColumn -Property 'DateTime' -Title 'DateTime' -ShowFilter
New-UDTableColumn -Property 'ComputerName' -Title 'ComputerName' -ShowFilter
New-UDTableColumn -Property 'Status' -Title 'Status' -ShowFilter
New-UDTableColumn -Property 'FullName' -Title 'FullName' -ShowFilter
) -Data ($SqlRecords | Sort-Object -Descending Id) -ShowPagination -PageSize 20 -Dense
} -Title "PRD" -Icon @{
id = 'd0f3391d-efa6-4210-b4dd-ef0cad028382'
type = 'icon'
}
@@ -0,0 +1,3 @@
New-UDPage -Name 'Home' -Content {
New-UDTypography -Text 'Home' -Id 'homeText'
} -Generated
@@ -0,0 +1,30 @@
$Navigation = @(
New-UDListItem -Label 'Home' -OnClick {
Invoke-UDRedirect -Url '/Home'
}
switch($env:computername){
"ITDWINAUTOT1" {
New-UDListItem -Label 'Infra-VMware.Snapshot_NPD' -OnClick {
Invoke-UDRedirect -Url '/NPD'
}
}
"ITDWINAUTOP1" {
New-UDListItem -Label 'Infra-VMware.Snapshot_PRD' -OnClick {
Invoke-UDRedirect -Url '/PRD'
}
}
}
New-UDListItem -Label 'Live Snapshots' -OnClick {
Invoke-UDRedirect -Url '/LiveSnapshots'
}
)
New-UDApp -Title 'PowerShell Universal' -Pages @(
Get-UDPage -Name 'Home'
switch($env:computername){
"ITDWINAUTOT1" { Get-UDPage -Name 'NPD' }
"ITDWINAUTOP1" { Get-UDPage -Name 'PRD' }
}
Get-UDPage -Name 'LiveSnapshots'
) -Navigation $Navigation
@@ -0,0 +1,57 @@
New-UDPage -Url "/PRD" -Name "PRD" -Content {
New-UDTypography -Text 'PRD'
<#New-UDForm -Content {
New-UDRow -Columns {
New-UDColumn -SmallSize 6 -LargeSize 6 -Content {
New-UDTextBox -Label "VMName" -Id VMName
New-UDTextBox -Label "DateTime" -Id DateTime
New-UDTextBox -Label "DurationHours" -Id DurationHours
New-UDTextBox -Label "Email" -Id Email
}
}
} -OnSubmit {
$InvokePSUScriptParams = @{
Script = 'New-ITDVMwareSnapshotTask.ps1'
VMName = $EventData.VMName;
DateTime = $EventData.DateTime;
DurationHours = $EventData.DurationHours;
Email = $EventData.Email
}
$InvokePSUScriuptResult = Invoke-PSUScript @InvokePSUScriptParams -Wait
Show-UDToast -Message ("attempting snapshot")
} #>
switch($env:COMPUTERNAME){
"ITDWINAUTOT1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
}
"ITDWINAUTOP1" {
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
}
}
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[PSUJobIdRequest],[PSUJobIdDelete],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [$Database].[dbo].[$SnapshotTable]"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
New-UDTable -Columns @(
New-UDTableColumn -Property 'Id' -Title 'Id' -ShowFilter
New-UDTableColumn -Property 'VMName' -Title 'VMName' -ShowFilter
New-UDTableColumn -Property 'DateTime' -Title 'DateTime'
New-UDTableColumn -Property 'RequestedBy' -Title 'RequestedBy' -ShowFilter
New-UDTableColumn -Property 'DurationHours' -Title 'DurationHours'
New-UDTableColumn -Property 'Status' -Title 'Status' -ShowFilter
New-UDTableColumn -Property 'NotifyEmail' -Title 'NotifyEmail' -ShowFilter
New-UDTableColumn -Property 'PSUJobIdRequest' -Title 'PSUJobIDRequest' -ShowFilter
New-UDTableColumn -Property 'PSUJobIdDelete' -Title 'PSUJobIDDelete' -ShowFilter
New-UDTableColumn -Property 'TakenDateTime' -Title 'TakenDateTime'
New-UDTableColumn -Property 'ExpireDateTime' -Title 'ExpireDateTime'
) -Data ($SqlRecords | Sort-Object -Descending Id) -ShowPagination -PageSize 20 -Dense
} -Title "PRD" -Icon @{
id = 'd0f3391d-efa6-4210-b4dd-ef0cad028382'
type = 'icon'
}
@@ -0,0 +1,3 @@
New-UDPage -Name 'Home' -Content {
New-UDTypography -Text 'Home' -Id 'homeText'
} -Generated
@@ -0,0 +1,13 @@
$Navigation = @(
New-UDListItem -Label 'Home' -OnClick {
Invoke-UDRedirect -Url '/Home'
}
New-UDListItem -Label 'AD Service Accounts' -OnClick {
Invoke-UDRedirect -Url '/ADServiceAccount'
}
)
New-UDApp -Title 'PowerShell Universal' -Pages @(
Get-UDPage -Name 'Home'
Get-UDPage -Name 'ADServiceAccount'
) -Navigation $Navigation
@@ -0,0 +1,34 @@
New-UDPage -Url "/ADServiceAccount" -Name "ADServiceAccount" -Content {
New-UDTypography -Text 'ADServiceAccount'
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$SqlQuery = "SELECT TOP (1000) [RequestedBy]
,[PSUJobId]
,[SamAccountName]
,[Description]
,[PasswordstateTitle]
,[PasswordstateList]
,[SnowCHGNum]
,[Status]
,[DomainName]
,[DateTime]
FROM [ITD-Systems-Automation].[dbo].[Infra_ActiveDirectory_Object_NewITDADServiceAccount_PRD]
ORDER BY [DateTime] DESC"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
New-UDTable -Columns @(
New-UDTableColumn -Property 'PSUJobId' -Title 'PSUJobId' -ShowFilter
New-UDTableColumn -Property 'DateTime' -Title 'DateTime' -ShowFilter
New-UDTableColumn -Property 'RequestedBy' -Title 'PSUJobId' -ShowFilter
New-UDTableColumn -Property 'SamAccountName' -Title 'SamAccountName' -ShowFilter
New-UDTableColumn -Property 'PasswordstateList' -Title 'PasswordstateList' -ShowFilter
New-UDTableColumn -Property 'PasswordstateTitle' -Title 'PasswordstateTitle' -ShowFilter
New-UDTableColumn -Property 'SnowCHGNum' -Title 'SnowCHGNum' -ShowFilter
New-UDTableColumn -Property 'Status' -Title 'Status' -ShowFilter
New-UDTableColumn -Property 'Domainname' -Title 'DomainName' -ShowFilter
) -Data ($SqlRecords | Sort-Object -Descending Id) -ShowPagination -PageSize 20 -Dense
} -Icon @{
type = 'icon'
id = '259b4c05-17df-4440-9907-57ab4df1e6c9'
}
@@ -0,0 +1,3 @@
New-UDPage -Name 'Home' -Content {
New-UDTypography -Text 'Home' -Id 'homeText'
} -Generated
@@ -0,0 +1,17 @@
$Navigation = @(
New-UDListItem -Label 'Home' -Icon (New-UDIcon -Icon Home) -OnClick {
Invoke-UDRedirect -Url '/home'
}
New-UDListItem -Label 'Users' -Icon (New-UDIcon -Icon User) -OnClick {
Invoke-UDRedirect -Url '/users'
}
New-UDListItem -Label 'Groups' -Icon (New-UDIcon -Icon Users) -OnClick {
Invoke-UDRedirect -Url '/groups'
}
)
New-UDApp -Title 'PowerShell Universal' -Pages @(
Get-UDPage -Name 'home'
Get-UDPage -Name 'users'
Get-UDPage -Name 'groups'
) -Navigation $Navigation
@@ -0,0 +1,26 @@
New-UDPage -Url "/Users" -Name "Users" -Content {
New-UDTypography -Text 'Roles assigned to this user:'
New-UDList -Content {
$Roles | ForEach-Object{
New-UDListItem -Label $_
}
}
New-UDTypography -Text 'Variables this user can access:'
$AllPSUVariables = Get-PSUVariable
$TableData = $AllPSUVariables | Select *,@{n='RoleStr';e={$_.Role -join ", "}},@{n='SecretValue';e={$SecretValue=Get-Childitem ("Secret:" + $_.Name) -ErrorAction SilentlyContinue;If($SecretValue -is [string]){"secure_string"}Else{$SecretValue}}},@{n='SecretUsername';e={(Get-Childitem ("Secret:" + $_.Name) -ErrorAction SilentlyContinue).Username}}
New-UDTable -Columns @(
New-UDTableColumn -Property 'Name' -Title 'Name' -ShowFilter
New-UDTableColumn -Property 'RoleStr' -Title 'Role' -ShowFilter
New-UDTableColumn -Property 'Type' -Title 'Type' -ShowFilter
New-UDTableColumn -Property 'Value' -Title 'Value' -ShowFilter
New-UDTableColumn -Property 'Secret' -Title 'Secret' -ShowFilter
New-UDTableColumn -Property 'SecretValue' -Title 'SecretValue' -ShowFilter
New-UDTableColumn -Property 'SecretUsername' -Title 'SecretUsername' -ShowFilter
) -Data $TableData -Dense
} -Title "Users" -Icon @{
type = 'icon'
id = '37c13667-6c5a-4cb1-a16b-49eaddd96d03'
}
@@ -0,0 +1,3 @@
New-UDPage -Name 'Home' -Content {
New-UDTypography -Text 'Home' -Id 'homeText'
} -Generated
@@ -0,0 +1,3 @@
New-UDApp -Title 'PowerShell Universal' -Pages @(
Get-UDPage -Name 'home'
)
@@ -0,0 +1,3 @@
New-UDPage -Name 'Home' -Content {
New-UDTypography -Text 'Home' -Id 'homeText'
} -Generated
@@ -0,0 +1,33 @@
$Navigation = @(
New-UDListItem -Label 'Home' -OnClick {
Invoke-UDRedirect -Url '/Home'
}
New-UDListItem -Label 'Server Build Request V1 (Current) Lookup' -OnClick {
Invoke-UDRedirect -Url '/ServerBuildRequestV1'
}
New-UDListItem -Label 'Application Server V2 (Previous) Lookup' -OnClick {
Invoke-UDRedirect -Url '/ApplicationServerV2'
}
New-UDListItem -Label 'CMDB Ci Lookup' -OnClick {
Invoke-UDRedirect -Url '/CMDBServerList'
}
New-UDListItem -Label 'AppNameLookup' -OnClick {
Invoke-UDRedirect -Url '/AppNameLookup'
}
New-UDListItem -Label 'CiLookup' -OnClick {
Invoke-UDRedirect -Url '/CiLookup'
}
New-UDListItem -Label 'AzureSizeHelper' -OnClick {
Invoke-UDRedirect -Url '/AzureVmSizeHelper'
}
)
AppNameLookup.ps1 - /AppNameLookup
New-UDApp -Title 'PowerShell Universal' -Pages @(
Get-UDPage -Name 'Home'
Get-UDPage -Name 'CMDBServerList'
Get-UDPage -Name 'ServerBuildRequestV1'
Get-UDPage -Name 'ApplicationServerV2'
Get-UDPage -Name 'AppNameLookup'
Get-UDPage -Name 'CiLookup'
Get-UDPage -Name 'AzureVmSizeHelper'
) -Navigation $Navigation
@@ -0,0 +1,58 @@
New-UDPage -Url "/AppNameLookup" -Name "AppNameLookup" -Content {
New-UDTypography -Id "disclaimer" -Text "This is querying the cmdb_ci_service_auto table in ServiceNow. This is live data being shown."
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$PropertyList = @(
@{
name = "name";
expression = { $_.name.display_value };
},
@{
name = "sys_id";
expression = { $_.sys_id.value } ;
},
@{
name = "u_primary_systems_admin";
expression = { $_.u_primary_systems_admin.display_value } ;
},
@{
name = "u_secondary_systems_admin";
expression = { $_.u_secondary_systems_admin.display_value } ;
},
@{
name = 'u_systems_owner';
expression = { $_.u_systems_owner.display_value};
}
)
#$Result = Get-ITDServiceNowRecord -Table cmdb_ci_server -Filter ("nameLIKE" + $EventData.CiName) -IncludeTotalCount | Select-Object -Property $PropertyList
$GetITDServiceNowRecordParams = @{
Table = 'cmdb_ci_service_auto';
IncludeTotalCount = $true;
Fields = @(
'name',
'sys_id',
'u_primary_systems_admin',
'u_secondary_systems_admin',
'u_systems_owner'
)
}
$Result = Get-ITDServiceNowRecord @GetITDServiceNowRecordParams | Select-Object -Property $PropertyList
$CmdbCiUrl = "https://northdakota.service-now.com/nav_to.do?uri=" + $Result.sys_class_name + ".do?sys_id=" + $Result.sys_id
New-UDTable -Columns @(
New-UDTableColumn -Property 'SNowUrl' -Title 'CmdbCiUrl' -Render { #https://northdakota.service-now.com/nav_to.do?uri=cmdb_ci_win_server.do?sys_id=8bc3ecd11b0154509d7ada01dd4bcb59
New-UDLink -Url ("https://northdakota.service-now.com/nav_to.do?uri=cmdb_ci_service_auto.do?sys_id=" + $EventData.sys_id) -Id "lnkSNow" -Content {
New-UDImage -Url "https://psuniversal.nd.gov/PSUniversal_Extras/servicenow_logo_icon_168835.png" -Height 20 -Width 20
}
}
New-UDTableColumn -Property 'name' -Title 'name' -ShowSort -ShowFilter
#New-UDTableColumn -Property 'sys_id' -Title 'sys_id' -ShowSort -ShowFilter
New-UDTableColumn -Property 'u_primary_systems_admin' -Title 'u_primary_systems_admin' -ShowSort -ShowFilter
New-UDTableColumn -Property 'u_secondary_systems_admin' -Title 'u_secondary_systems_admin' -ShowSort -ShowFilter
New-UDTableColumn -Property 'u_systems_owner' -Title 'u_systems_owner' -ShowSort -ShowFilter
) -Data ($Result | sort-object Name) -ShowPagination -Dense -PageSize 50
} -Title "AppNameLookup" -Icon @{
id = '9fdceac8-807e-4d5e-acda-3d477d77fdb4'
type = 'icon'
}
@@ -0,0 +1,25 @@
New-UDPage -Url "/ApplicationServerV2" -Name "ApplicationServerV2" -Content {
New-UDTypography -Text 'Application Server request items (RITMs) submitted between 2023/02/27 and 2024/06/25 in which the field "VM Work Needed" is set to "Yes"'
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = 'ServiceNow_RitmDump_ApplicationServerV2'
$SqlQuery = "SELECT [number],[sys_id],[opened_at],[requested_for],[short_description],[request_type],[application_name],[environment],[additional_comments],[vm_work_needed],[server_name],[host_name],[server_type],[operating_system],[target_platform],[processors],[memory_gb],[cidr_block],[data_center],[licensing_restrictions],[agency_name],[application_info],[support_hours],[dr_protection],[startup_priority],[disk_1_os],[disk_2_swap_disk],[disk_3],[disk_4],[disk_5],[disk_6],[disk_7],[disk_8],[disk_9],[disk_10],[disk_11],[disk_12],[disk_13],[disk_14],[disk_15],[disk_16] FROM [$Database].[dbo].[$Table] WHERE vm_work_needed = '1'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
New-UDTable -Columns @(
New-UDTableColumn -Property 'number' -Title 'number' -ShowSort
New-UDTableColumn -Property 'opened_at' -Title 'opened_at'
New-UDTableColumn -Property 'server_name' -Title 'server_name' -ShowFilter
New-UDTableColumn -Property 'host_name' -Title 'host_name' -ShowFilter
New-UDTableColumn -Property 'requested_for' -Title 'requested_for' -ShowFilter
New-UDTableColumn -Property 'request_type' -Title 'request_type' -ShowFilter
New-UDTableColumn -Property 'environment' -Title 'environment' -ShowFilter
New-UDTableColumn -Property 'additional_comments' -Title 'additional_comments' -ShowFilter
) -Data ($SqlRecords | Select *,@{n='Open';e={$_.sys_id}} | Sort-Object -Descending number) -Dense -ShowPagination -PageSize 20
} -Title "ApplicationServerV2" -Icon @{
id = 'd9dc64f6-9f4b-432a-866a-d3189529528b'
type = 'icon'
}
@@ -0,0 +1,23 @@
New-UDPage -Url "/AzureVmSizeHelper" -Name "AzureVmSizeHelper" -Content {
$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
$TableData = Get-AzVmSize -Location centralus | Select *,`
@{n='MemoryInGB';e={$_.MemoryInMb / 1024}}, `
@{n='OSDiskSizeInGB'; e={$_.OsDiskSizeInMb / 1024}}, `
@{n='ResourceDiskSizeInGB'; e={$_.ResourceDiskSizeInMB / 1024}} | Sort-Object NumberOfCores,MemoryInGB
New-UDTable -Columns @(
New-UDTableColumn -Property 'Name' -Title 'Name' -ShowSort -ShowFilter
New-UDTableColumn -Property 'NumberOfCores' -Title 'NumberOfCores' -ShowSort -ShowFilter
New-UDTableColumn -Property 'MemoryInGB' -Title 'MemoryInGB' -ShowFilter -ShowSort
New-UDTableColumn -Property 'OSDiskSizeInGB' -Title 'OSDiskSizeInGB' -ShowFilter -ShowSort
New-UDTableColumn -Property 'ResourceDiskSizeInGB' -Title 'ResourceDiskSizeInGB' -ShowFilter -ShowSort
) -Data $TableData -Dense
} -Title "AzureVmSizeHelper" -Icon @{
type = 'icon'
id = 'f45c0541-5f78-4c00-899b-548e1bbabb04'
}
@@ -0,0 +1,154 @@
New-UDPage -Url "/CMDBServerList" -Name "CMDBServerList" -Content {
# Use Get-UDPage -Name 'CmdbServer' to use this page in your dashboard
<#
New-UDCard -Content {
New-UDList -children {
New-UDListItem -Label "Enter the Name of the Cmdb Ci. Usually host name, not FQDN. `nFor example: itdsccmp2.nd.gov, enter itdsccmp2. The search is using 'LIKE' comparsion operator, so wildcards are automatically applied at both sides of the entered value. "
New-UDListItem -Label 'This search is a live query of the ServiceNow Cmdb.'
New-UDListItem -Label 'This is a work in progress. Use at your own discretion.'
}
}#>
New-UDForm -Id 'CiLookup' -Content {
New-UDRow -Columns {
New-UDColumn -SmallSize 6 -LargeSize 6 -Content {
New-UDTextbox -Id 'CiName'
}
}
} -OnValidate {
$FormContent = $EventData
if ($FormContent.CiName -eq $null -or $FormContent.VMName -eq '') {
New-UDFormValidationResult -ValidationError "CiName is required"
}
else {
New-UDFormValidationResult -Valid
}
} -OnSubmit {
Show-UDToast -Message ("Querying ServiceNow table cmdb_ci_server for record with name " + $EventData.Name) -Duration 20000
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$PropertyList = @(
@{
name = "name";
expression = { $_.name.display_value };
},
@{
name = "dns_domain";
expression = { $_.dns_domain.display_value } ;
},
@{
name = "environment";
expression = { $_.environment.display_value } ;
},
@{
name = 'operational_status';
expression = { $_.operational_status.display_value};
}
@{
name = 'sys_id';
expression = { $_.sys_id.value };
}
@{
name = 'sys_class_name';
expression = { $_.sys_class_name.value }
},
@{
name = "u_nd_type";
expression = { $_.u_nd_type.display_value }
},
@{
name = "u_nd_application_svc";
expression = { $_.u_nd_application_svc.display_value }
},
@{
name = "u_nd_licensing_restrictions";
expression = { $_.u_nd_licensing_restrictions.display_value }
},
@{
name = "u_support_hours";
expression = { $_.u_support_hours.display_value }
},
@{
name = "u_nd_dr_protection";
expression = { $_.u_nd_dr_protection.display_value };
},
@{
name = "u_srm_recovery_type";
expression = { $_.u_srm_recovery_type.display_value }
},
@{
name = "os";
expression = { $_.os.display_value }
},
@{
name = "os_version";
expression = { $_.os_version.display_value }
},
@{
name = "model_id";
expression = { $_.model_id.display_value }
}
)
#$Result = Get-ITDServiceNowRecord -Table cmdb_ci_server -Filter ("nameLIKE" + $EventData.CiName) -IncludeTotalCount | Select-Object -Property $PropertyList
$GetITDServiceNowRecordParams = @{
#Filter = "model_id=3161ee6c1bf810502653997fbd4bcb4c^ORmodel_id%253Da75f244c1bd75014bba0113fad4bcb72"
Filter = "model_idLIKEVMware^ORmodel_idLIKEMicrosoft"
Table = 'cmdb_ci_server';
IncludeTotalCount = $true;
Fields = @(
'name',
'sys_id',
'dns_domain',
'sys_class_name',
'operational_status',
'environment',
'u_nd_type',
'model_id',
'os',
'os_version',
'u_nd_application_svc',
'u_nd_licensing_restrictions',
'u_nd_dr_protection',
'u_srm_recovery_type',
'u_support_hours'
)
}
$Result = Get-ITDServiceNowRecord @GetITDServiceNowRecordParams | Select-Object -Property $PropertyList
$CmdbCiUrl = "https://northdakota.service-now.com/nav_to.do?uri=" + $Result.sys_class_name + ".do?sys_id=" + $Result.sys_id
New-UDTable -Columns @(
New-UDTableColumn -Property 'CmdbCiUrl' -Title 'CmdbCiUrl' -Render { #https://northdakota.service-now.com/nav_to.do?uri=cmdb_ci_win_server.do?sys_id=8bc3ecd11b0154509d7ada01dd4bcb59
New-UDLink -Url ("https://northdakota.service-now.com/nav_to.do?uri=" + $EventData.sys_class_name + ".do?sys_id=" + $EventData.sys_id) -Id "lnkCmdbCi" -Content {
New-UDImage -Url "https://psuniversal.nd.gov/PSUniversal_Extras/servicenow_logo_icon_168835.png" -Height 20 -Width 20
}
}
New-UDTableColumn -Property 'name' -Title 'name' -ShowSort -ShowFilter
New-UDTableColumn -Property 'dns_domain' -Title 'dns_domain' -ShowFilter
New-UDTableColumn -Property 'u_nd_application_svc' -Title 'u_nd_application_svc' -ShowFilter
New-UDTableColumn -Property 'environment' -Title 'environment' -ShowFilter
New-UDTableCOlumn -Property 'operational_status' -Title 'operational_status' -ShowFilter
New-UDTableColumn -Property 'u_nd_type' -Title 'u_nd_type' -ShowFilter
#New-UDTableColumn -Property 'model_id' -Title 'model_id' -ShowFilter
#New-UDTableColumn -Property 'os' -Title 'os' -ShowFilter
#New-UDTableColumn -Property 'os_version' -Title 'os_version' -ShowFilter
New-UDTableColumn -Property 'u_nd_licensing_restrictions' -Title 'u_nd_licensing_restrictions' -ShowFilter
New-UDTableColumn -Property 'u_support_hours' -Title 'u_support_hours' -ShowFilter
New-UDTableColumn -Property 'u_nd_dr_protection' -Title 'u_nd_dr_protection' -ShowFilter
New-UDTableColumn -Property 'u_srm_recovery_type' -Title 'u_srm_recovery_type' -ShowFilter
) -Data ($Result | sort-object Name) -ShowPagination -Dense -PageSize 50
} -OnProcessing {
}
New-UDCard -Id 'Result'
} -Title "CMDBServerList" -Icon @{
id = 'dc0de7d9-022b-4e24-a7c7-7f0e59710542'
type = 'icon'
}
@@ -0,0 +1,97 @@
New-UDPage -Url "/CiLookup" -Name "CiLookup" -Content {
New-UDGrid -Container -Children {
New-UDGrid -Item -ExtraSmallSize 4 -Children {
New-UDCard -Title "General Information" -Content {
#New-UDButton -Text "Button 1"
New-UDRow -Columns {
New-UDColumn -Size 4 -Content {
New-UDTextBox -Label "Name" -Id "Name" -Value "itddefghijklmno.ndcloud.gov" -FullWidth
}
New-UDColumn -Size 4 -Content {
New-UDTextBox -Label "LicensingRestrictions" -Id "LicensingRestrictions" -Value "Microsoft SQL Enterprise"
}
}
}
}
New-UDGrid -Item -ExtraSmallSize 4 -Children {
New-UDCard -Title "Support Information" -Content {
#New-UDButton -Text "Button 2"
New-UDRow -Columns {
New-UDColumn -Size 4 -Content {
New-UDTextBox -Label "AppName" -Id "AppName"
}
New-UDColumn -Size 4 -Content {
New-UDTextBox -Label "Support Hours" -Id "Support Hours"
}
}
}
}
} -Id "GridGeneral"
New-UDContainer -Content {
New-UDLayout -Columns 2 - -Content {
#New-UDTypography "Row 1, Col 1"
New-UDTextBox -Label "Name" -Value "itddefghijklmno.ndcloud.gov" -FullWidth
#New-UDTypography "Row 1, Col 2"
New-UDTextBox -Label "AppName" -Value "Infra-POS-SomeStupidApp" -FullWidth
New-UDTypography "Row 2, Col 1"
New-UDTypography "Row 2, Col 2"
}
}
$tablePwd = [ordered]@{
'Password Expiration' = "itdsomething.nd.gov"
'Account Expiration' = "ITD-POS-StupidName"
'Last Logon Timestamp' = "Microsoft SQL Enterperise"
}
$Data = , @($tablePwd.GetEnumerator())
$DateColumns = @(
New-UDTableColumn -Property Name -Title " "
New-UDTableColumn -Property Value -Title " "
)
New-UDTable -Id "PasswordInfo" -Title "Password and Account Info" -Data $Data[0] -Columns $DateColumns -Dense
New-UDButton -Text 'Full Width' -OnClick {
Show-UDModal -Content {
New-UDGrid -Container -Children {
New-UDCard -Title "General" -Content {
New-UDElement -Tag 'div' -Id 'addElement'
New-UDTextBox -Id "Name" -Label "Name" -Value "servernamehere.nd.gov"
New-UDTextBox -Id "Operational Status" -Label "Status" -Value "Operational"
New-UDTextBox -Id "AppName" -Label "AppName" -Value "ITD-POS-StupidNameHere"
New-UDTextBox -Id "Support Hours" -Label "Support Hours" -Value "All Day Every Day"
}
New-UDCard -Title "Hardware" -Content {
New-UDTextBox -Id "Datacenter" -Label "Datacenter" -Value "Bismarck"
New-UDTextBox -Id "Environment" -Label "Environment" -Value "Production"
New-UDTextBox -Id "DR Protection" -Label "DR Protection" -Value "VMware: RPO 04:00"
New-UDTextBox -Id "Datacenter" -Label "Datacenter" -Value "Bismarck"
New-UDTextBox -Id "Environment" -Label "Environment" -Value "Production"
New-UDTextBox -Id "DR Protection" -Label "DR Protection" -Value "VMware: RPO 04:00"
New-UDTextBox -Id "OperatingSystem" -Label "Operating System" -Value "Windows Server 2022"
New-UDTextBox -Id "CPU" -Label "CPU" -Value "4"
New-UDTextBox -Id "MemoryGB" -Label "MemoryGB" -Value "12"
New-UDTextBox -Id "DiskGB" -Label "DiskGB" -Value "1197"
}
New-UDCard -Title "Software" -Content {
New-UDTextBox -Id "LicensingRestrictions" -Label "LicensingRestrictions" -Value "Microsoft SQL Enterprise"
New-UDTextBox -Id "OperatingSystem" -Label "Operating System" -Value "Windows Server 2022"
}
}
#New-UDDynamic
} -FullWidth -MaxWidth 'md'
}
} -Title "CiLookup" -Icon @{
id = '3743b2ed-0278-4678-8a47-e22ad4514afb'
type = 'icon'
}
@@ -0,0 +1,4 @@
New-UDPage -Url "/CiTest" -Name "CiTest" -Content {
} -Title "CiTest" -Icon @{
} -Generated
@@ -0,0 +1,39 @@
New-UDPage -Url "/ServerBuildRequestV1" -Name "ServerBuildRequestV1" -Content {
New-UDTypography -Text "`nServer Build Request request items (RITMs) submitted after 2024/06/25"
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = 'ServiceNow_RitmDump_ServerBuildRequestV1'
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$SqlQuery = "SELECT [RitmNum],
[RitmSysId],
[opened_at],
[requested_for],
[request_type],
[environment]
,[host_name_ref]
,[host_name]
FROM [ITD-Systems-Automation].[dbo].[ServiceNow_RitmDump_ServerBuildRequestV1]"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
New-UDTable -Dense -ShowPagination -PageSize 20 -Size small -Data ($SqlRecords | Sort-Object -Descending opened_at) -Columns @(
New-UDTableColumn -Property 'RitmUrl' -Title 'RitmUrl' -Render {
New-UDLink -Url ("https://northdakota.service-now.com/nav_to.do?uri=sc_req_item.do?sys_id=" + $EventData.RitmSysId) -Id "lnkRitm" -Content {
New-UDImage -Url "https://psuniversal.nd.gov/PSUniversal_Extras/servicenow_logo_icon_168835.png" -Height 20 -Width 20
}
}
New-UDTableColumn -Property 'RitmNum' -Title 'RitmNum' -ShowFilter
New-UDTableColumn -Property 'opened_at' -Title 'opened_at' -ShowFilter
New-UDTableColumn -Property 'host_name' -Title 'host_name' -ShowFilter
New-UDTableColumn -Property 'requested_for' -Title 'requested_for' -ShowFilter
New-UDTableColumn -Property 'request_type' -Title 'request_type' -ShowFilter
New-UDTableColumn -Property 'environment' -Title 'environment' -ShowFilter
#New-UDTableColumn -Property 'additional_comments' -Title 'additional_comments' -ShowFilter
)
} -Title "ServerBuildRequestV1" -Icon @{
}
@@ -0,0 +1,11 @@
New-UDPage -Url "/Home" -Name "Home" -Content {
New-UDTypography -text 'Use left side navigation to view various ServiceNow queries' -id 'homeText' -noWrap
} -Generated -Layout (
New-UDPageLayout -Large @(
New-UDItemLayout -Id 'homeText' -Row 0 -Column 0 -RowSpan 1 -ColumnSpan 1
) -Medium @(
) -Small @(
) -ExtraSmall @(
) -ExtraExtraSmall @(
)
)
@@ -0,0 +1,21 @@
$Navigation = @(
New-UDListItem -Label 'Home' -OnClick {
Invoke-UDRedirect -Url '/Home'
}
New-UDListItem -Label 'ServerBuildRequestV1' -OnClick {
Invoke-UDRedirect -Url '/ServerBuildRequestV1'
}
New-UDListItem -Label 'ApplicationServerV2' -OnClick {
Invoke-UDRedirect -Url '/ApplicationServerV2'
}
New-UDListItem -Label 'SpCmdbCompare' -OnClick {
Invoke-UDRedirect -Url '/SpCmdbCompare'
}
)
New-UDApp -Title 'PowerShell Universal' -Pages @(
Get-UDPage -Name 'Home'
Get-UDPage -Name 'ApplicationServerV2'
Get-UDPage -Name 'ServerBuildRequestV1'
Get-UDPage -Name 'SpCmdbCompare'
) -Navigation $Navigation
@@ -0,0 +1,25 @@
New-UDPage -Url "/ApplicationServerV2" -Name "ApplicationServerV2" -Content {
New-UDTypography -Text 'Application Server request items (RITMs) submitted between 2023/02/27 and 2024/06/25 in which the field "VM Work Needed" is set to "Yes"'
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = 'ServiceNow_RitmDump_ApplicationServerV2'
$SqlQuery = "SELECT [number],[sys_id],[opened_at],[requested_for],[short_description],[request_type],[application_name],[environment],[additional_comments],[vm_work_needed],[server_name],[host_name],[server_type],[operating_system],[target_platform],[processors],[memory_gb],[cidr_block],[data_center],[licensing_restrictions],[agency_name],[application_info],[support_hours],[dr_protection],[startup_priority],[disk_1_os],[disk_2_swap_disk],[disk_3],[disk_4],[disk_5],[disk_6],[disk_7],[disk_8],[disk_9],[disk_10],[disk_11],[disk_12],[disk_13],[disk_14],[disk_15],[disk_16] FROM [$Database].[dbo].[$Table] WHERE vm_work_needed = '1'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
New-UDTable -Columns @(
New-UDTableColumn -Property 'number' -Title 'number' -ShowSort
New-UDTableColumn -Property 'opened_at' -Title 'opened_at'
New-UDTableColumn -Property 'server_name' -Title 'server_name' -ShowFilter
New-UDTableColumn -Property 'host_name' -Title 'host_name' -ShowFilter
New-UDTableColumn -Property 'requested_for' -Title 'requested_for' -ShowFilter
New-UDTableColumn -Property 'request_type' -Title 'request_type' -ShowFilter
New-UDTableColumn -Property 'environment' -Title 'environment' -ShowFilter
New-UDTableColumn -Property 'additional_comments' -Title 'additional_comments' -ShowFilter
) -Data ($SqlRecords | Select *,@{n='Open';e={$_.sys_id}} | Sort-Object -Descending number) -Dense -ShowPagination -PageSize 20
} -Icon @{
type = 'icon'
id = 'e91ed4ef-cecd-448a-9204-2b453db9db03'
}
@@ -0,0 +1,42 @@
New-UDPage -Url "/ServerBuildRequestV1" -Name "ServerBuildRequestV1" -Content {
New-UDTypography -Text "`nServer Build Request request items (RITMs) submitted after 2024/06/25"
$ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
$Database = "ITD-Systems-Automation"
$Table = 'ServiceNow_RitmDump_ServerBuildRequestV1'
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$SqlQuery = "SELECT [RitmNum],
[RitmSysId],
[opened_at],
[requested_for],
[request_type],
[environment]
,[host_name_ref]
,[host_name]
FROM [ITD-Systems-Automation].[dbo].[ServiceNow_RitmDump_ServerBuildRequestV1]"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
New-UDTable -Dense -ShowPagination -PageSize 20 -Size small -Data ($SqlRecords | Sort-Object -Descending opened_at) -Columns @(
New-UDTableColumn -Property 'RitmUrl' -Title 'RitmUrl' -Render {
New-UDLink -Url ("https://northdakota.service-now.com/nav_to.do?uri=sc_req_item.do?sys_id=" + $EventData.RitmSysId) -Id "lnkRitm" -Content {
New-UDImage -Url "https://psuniversal.nd.gov/PSUniversal_Extras/servicenow_logo_icon_168835.png" -Height 20 -Width 20
}
}
New-UDTableColumn -Property 'RitmNum' -Title 'RitmNum' -ShowFilter
New-UDTableColumn -Property 'opened_at' -Title 'opened_at' -ShowFilter
New-UDTableColumn -Property 'host_name' -Title 'host_name' -ShowFilter
New-UDTableColumn -Property 'requested_for' -Title 'requested_for' -ShowFilter
New-UDTableColumn -Property 'request_type' -Title 'request_type' -ShowFilter
New-UDTableColumn -Property 'environment' -Title 'environment' -ShowFilter
#New-UDTableColumn -Property 'additional_comments' -Title 'additional_comments' -ShowFilter
)
} -Icon @{
id = '7d67b921-68aa-4085-84e8-025e92671771'
type = 'icon'
}
@@ -0,0 +1,3 @@
New-UDPage -Name 'Home' -Content {
New-UDTypography -Text 'Home' -Id 'homeText'
} -Generated