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,667 @@
<#
.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
$NewITDWindowsVmVMwareParams = @{
ComputerName = 'itdzmtest300.nd.gov';
Environment = "Test";
AppName = "ITD-POC-zmeier";
Credential = $PrvCred;
}
New-ITDWindowsVmVMware @NewITDWindowsVmVMwareParams
#>
function New-ITDWindowsVmVMwareStep2 {
[CmdletBinding()]
param (
[string]
$FQDN,
[string]
$AppName,
[string]
$VMEnvironment,
[PSCredential]
$Credential
)
begin {
}
process {
Write-Verbose -Message "Start New-ITDWindowsVmVMwareStep2"
$FQDN = $FQDN.ToLower()
$HostName = $FQDN.split('.')[0]
$DomainName = $FQDN.Substring($FQDN.IndexOf(".") + 1)
$VM = Get-VM -Name $FQDN
$ViServer = $VM.Uid.split('@')[1].split(':')[0]
$VMTagAssignments = Get-TagAssignment -Entity $VM
#$AppName = $VMTagAssignments | Where-Object { $_.Tag.Category.Name -eq "AppName" }
#$DTAP = $VMTagAssignments | Where-Object { $_.Tag.Category.Name -eq "DTAP" }
Write-Verbose -Message "FQDN: $FQDN"
Write-Verbose -Message "HostName: $HostName"
$GuestVMLocalCredential = Get-ITDPassword -Title $FQDN -UserName itdadmin -Credential $Credential -ErrorAction SilentlyContinue
$GuestCredentialAB = New-Object System.Management.Automation.PSCredential ('itdadmin', ($GuestVMLocalCredential.GetNetworkCredential().Password | ConvertTo-SecureString -AsPlainText -Force))
$GuestCredentialBB = New-Object System.Management.Automation.PSCredential ('Administrator', ($GuestVMLocalCredential.GetNetworkCredential().Password | ConvertTo-SecureString -AsPlainText -Force))
If ($null -eq $GuestVMLocalCredential) {
Write-Error -Message "Credentials not found in Passwordstate" -ErrorAction Stop
}
Else {
Write-Verbose -Message "Credentials found in Passwordstate"
Write-Verbose -Message ("username: + " + $GuestVMLocalCredential.UserName)
}
<# Wait for Customization to finish
$VMStarted = $false
$VMCustomizationStarted = $false
$VMCustomizationResult = $false
While ($VMStarted -eq $false -or $VMCustomizationStarted -eq $false -or $VMCustomizationResult -eq $false) {
Write-Warning ("Customization wait loop started " + (Get-Date))
Write-Verbose "Current Status:"
Write-Verbose ("VMStarted: " + $VMStarted)
Write-Verbose ("VMCustomizationStarted: " + $VMCustomizationStarted)
Write-Verbose ("VMCustomizationResult: " + $VMCustomizationResult)
$GetVIEventRuntime = Measure-Command -Expression { $VMEvents = Get-VIEvent -Entity $VM -Server $ViServer -ErrorAction SilentlyContinue } ## takes a long time to execute
Write-Verbose ("Get-VIEvent last run time: " + $GetVIEventRuntime.TotalSeconds + " seconds")
If ($VMStarted -eq $false) {
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "VMStartingEvent" })) {
$VMStarted = $true
Write-Warning "[$FQDN]:Virtual machine started"
}
}
If ($VMCustomizationStarted -eq $false) {
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "CustomizationStartedEvent" })) {
$VMCustomizationStarted = $true
Write-Warning "[$FQDN]:Virtual machine customization started"
}
}
If ($VMCustomizationResult -eq $false) {
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "CustomizationFailed" })) {
$VMCustomizationResult = $true
Write-Error "[$FQDN]:Virtual machine customization failed"
Exit
Exit
}
If (@($VMEvents | Where-Object { $_.GetType().Name -eq "CustomizationSucceeded" })) {
$VMCustomizationResult = $true
Write-Warning "[$FQDN]:Virtual machine customization completed"
}
}
} #>
# OS
Write-Verbose -Message "Begin Post-Sysprep OS Guest Customization"
Write-Verbose -Message "Assigning WMI Tag 000-Prod, SCCM will change it later if required"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
# Move DVD Drive Mount
try {
Write-Verbose "Create new Class"
$Class = New-Object System.Management.ManagementClass("root\cimv2", [String]::Empty, $null);
$Class["__CLASS"] = "ITD";
$Class.Qualifiers.Add("Static", $true)
$Class.Properties.Add("MyKey", [System.Management.CimType]::String, $false)
$Class.Properties["MyKey"].Qualifiers.Add("Key", $true)
$Class.Properties.Add("LastModified", [System.Management.CimType]::String, $false)
$Class.Properties.Add("DTAP", [System.Management.CimType]::String, $false)
$Class.Properties.Add("Baseline", [System.Management.CimType]::String, $false)
$Class.Put()
Write-Verbose "Create single ITD Object"
Set-WmiInstance -Class ITD -Arguments @{LastModified = (Get-Date); DTAP = "Prod"; Baseline = "000" }
}
catch {
Throw $_
Break
}
}
Write-Verbose -Message "Checking for DVD drive, and moving it to Z:\"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
Write-Host "hello1"
# Move DVD Drive Mount
try {
$dvd_letter = 'Z'
$dvd = Get-WmiObject -Class Win32_Volume -Filter "DriveType=5" | Select-Object -First 1
if ($dvd.Name -notmatch $dvd_letter) {
Write-Verbose -Message "Found DVD drive, switching to $dvd_letter`:"
Set-WmiInstance -InputObject $dvd -Arguments @{DriveLetter = "$dvd_letter`:" } | Out-Null
Write-Verbose -Message "DVD drive moved to drive letter $dvd_letter`:"
}
else {
Write-Verbose -Message "No DVD drive changes required, continuing..."
}
}
catch {
Throw $_
Break
}
}
Write-Verbose -Message "Checking for unpartitioned space on C: volume and expanding"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
Write-Host "hello1"
# Expand C: Partition To Maximum Extent
try {
$cSize = ( Get-Partition -DriveLetter C ).Size
$cMaxSize = ( Get-PartitionSupportedSize -DriveLetter C ).SizeMax
if ($cSize -lt $cMaxSize) {
Write-Verbose -Message "Expanding C: from $($csize / 1GB)GB to $($cMaxSize / 1GB)GB..."
Resize-Partition -DriveLetter C -Size $cMaxSize
Write-Verbose -Message "C: expanded to $($cMaxSize / 1GB)GB."
}
else {
Write-Verbose -Message "C: is already at maximum size, continuing..."
}
}
catch {
Throw $_
Break
}
}
Write-Verbose -Message "Start Extra Disk(s) config"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
# Initialize Additional Disks
try {
# Non-initialized and MBR-initialized disks will have 0 partitions by default, but GPT-initialized disks will have 1 system reserved partition by default
$Disks = Get-Disk | Where-Object { $_.NumberOfPartitions -eq 0 -or ( $_.PartitionStyle -eq 'GPT' -and $_.NumberOfPartitions -eq 1 ) } | Sort-Object -Property Number
If ($Disks) {
Write-Verbose -Message "Found $(@($disks).Count) unpartitioned disks."
ForEach ($disk in $disks) {
if ($disk.IsOffline) {
Set-Disk $disk.Number -IsOffline $false
Write-Verbose -Message "Brought disk $($disk.Number)($("{0:n0}GB" -f ($disk.Size / 1GB))) online..."
}
if ($disk.IsReadOnly) { Set-Disk $disk.Number -IsReadOnly $false }
if ($disk.PartitionStyle -eq 'RAW') { Initialize-Disk $disk.Number -PartitionStyle GPT -ErrorAction SilentlyContinue }
$diskParam = @{
FileSystem = 'NTFS'
Confirm = $false
}
$driveLetter = [Int][Char]'D'
while (Get-Volume -DriveLetter $([Char]$driveLetter) -ErrorAction SilentlyContinue) {
$driveLetter++
}
$diskParam.DriveLetter = [Char]$driveLetter
if (@($disks).IndexOf($disk) -eq 0 -and (-not (Get-Volume -DriveLetter D -ErrorAction SilentlyContinue))) {
$diskParam.NewFileSystemLabel = 'Temporary Storage'
}
elseif (@($disks).IndexOf($disk) -eq 1 -and (-not (Get-Volume -DriveLetter E -ErrorAction SilentlyContinue))) {
$diskParam.NewFileSystemLabel = 'Data'
}
[void](New-Partition -DiskNumber $disk.Number -DriveLetter $diskParam.DriveLetter -UseMaximumSize)
[void](Format-Volume @diskParam)
}
}
Else {
Write-Verbose -Message "No unpartitioned disks found, continuing..." -Verbose
}
}
catch {
Throw $_
Break
}
}
Write-Verbose -Message "Start Page File Configuration"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
# Configure Page File
if (Get-Partition -DriveLetter D -ErrorAction SilentlyContinue) {
Write-Verbose -Message "Setting up pagefile.sys on D:..." -Verbose
try {
if (-not [IO.File]::Exists('D:\pagefile.sys')) {
$autoPage = Get-WmiObject -Class Win32_ComputerSystem -EnableAllPrivileges
$autoPage.AutomaticManagedPagefile = $false
[void]$autoPage.Put()
Write-Verbose -Message "Disabled automatic pagefile management." -Verbose
$pageFile = Get-WmiObject -Class Win32_PageFileSetting -EnableAllPrivileges
$pageFile.Delete()
Write-Verbose -Message "Deleted C:\pagefile.sys." -Verbose
Set-WmiInstance -Class Win32_PageFileSetting -Arguments @{ Name = "D:\pagefile.sys"; InitialSize = 0; MaximumSize = 0; } -EnableAllPrivileges | Out-Null
Write-Verbose -Message "System managed page file created on D:\pagefile.sys." -Verbose
}
else {
Write-Verbose -Message "Pagefile already configured on D:, continuing..." -Verbose
}
}
catch {
Throw $_
Break
}
}
else {
Write-Verbose -Message "Page file drive not found, cannot set up page file. Continuing server configuration..." -Verbose
Write-Warning "Page file drive not found, cannot set up page file. Continuing server configuration..."
}
}
Write-Verbose -Message "Enabling Remote Management"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
# Configure Remote Management (RDP/PoSH)
try {
Write-Verbose -Message "Checking WinRM..." -Verbose
if (Test-WSMan -ErrorAction SilentlyContinue) {
Write-Verbose -Message "WinRM is already enabled."
}
else {
Enable-PSRemoting -Force
Write-Verbose -Message "WinRM is now enabled."
}
Write-Verbose -Message "Checking RDP..." -Verbose
$RDP = Get-WmiObject Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices
$NLA = Get-WmiObject Win32_TSGeneralSetting -Namespace root\cimv2\TerminalServices -Filter "TerminalName='RDP-tcp'"
if ($RDP.AllowTSConnections -eq 0) {
Write-Verbose -Message "RDP is disabled, enabling..."
$RDP.SetAllowTSConnections(1, 1) | Out-Null
Write-Verbose -Message "RDP is enabled."
}
else {
Write-Verbose -Message "RDP is already enabled, checking NLA security..."
}
if ($NLA.UserAuthenticationRequired -eq 0) {
Write-Verbose -Message "RDP is not NLA secured, enabling..."
$NLA.SetUserAuthenticationRequired(1) | Out-Null
Write-Verbose -Message "RDP is now NLA secured."
}
else {
Write-Verbose -Message "RDP is already NLA secured."
}
}
catch {
Throw $_
Break
}
}
Write-Verbose -Message "Checking current power plan, set to High Performance"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
# Configure Power Plan
try {
$powerPlans = powercfg -l
if ($powerPlans -match '\*$' -notmatch 'High performance') {
$currentPlan = [regex]::Match($powerPlans, '(?<=(\())[^)]+(?=(\)\s\*))').Value
Write-Verbose -Message "Power plan is currently set to $currentPlan, changing to High Performance..." -Verbose
$highPerformance = [regex]::Match($powerPlans, '([\d\w-\S]+)(?=\s+\(High performance\))').Value
[void](powercfg -setactive $highPerformance)
Write-Verbose -Message "Power plan set to High Performance." -Verbose
}
else {
Write-Verbose -Message "Power plan already configured for High Performance." -Verbose
}
[void](& w32tm.exe /resync /nowait)
}
catch {
Throw $_
Break
}
}
$TimeSyncFunc = {
# Configure Time/Date Settings
Write-Verbose -Message "Checking current time/date settings..."
$Domain = "<DomainName>"
try {
if ((Get-TimeZone).Id -ne 'Central Standard Time') {
Write-Verbose -Message "Current time zone set to $((Get-TimeZone).Id), setting to Central Standard Time." -Verbose
Set-TimeZone -Id 'Central Standard Time'
Write-Verbose -Message "Time zone set to Central Standard Time." -Verbose
}
else {
Write-Verbose -Message "Time zone is already set to Central Standard Time." -Verbose
}
}
catch {
Throw $_
Break
}
}
$TimeSyncScriptBlock = $TimeSyncFunc -replace '<DomainName>', $DomainName
$VM | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText $TimeSyncScriptBlock
#>
Write-Verbose -Message "Enable the server manager performance monitors"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
# Enable Performance Counters
try {
if (Get-ScheduledTask -TaskName "Server Manager Performance Monitor" | Where-Object State -NE "Running" -ErrorAction SilentlyContinue) {
Enable-ScheduledTask -TaskPath "\Microsoft\Windows\PLA\" -TaskName "Server Manager Performance Monitor" | Start-ScheduledTask
Write-Verbose -Message "Performance monitors enabled." -Verbose
}
else {
Write-Verbose -Message "Performance monitors already enabled, continuing..." -Verbose
}
}
catch {
Throw $_
Break
}
}
Write-Verbose -Message "Disable Windows Firewall"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText {
# Disable Windows Firewall
Write-Verbose -Message "Checking for active Windows Firewall..." -Verbose
if ((Get-NetFirewallProfile).Enabled -contains 'True') {
Write-Verbose -Message "Windows Firewall is still enabled, disabling it..."
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False
Write-Verbose -Message "Windows Firewall disabled." -Verbose
}
else {
Write-Verbose -Message "Windows Firewall already disabled, continuing..." -Verbose
}
}
# Active Directory
Write-Verbose -Message "Join Active Directory"
Write-Verbose -Message "Domain is $DomainName"
Write-Verbose -Message "AppName is $AppName"
switch ($DomainName) {
'nd.gov' {
$SearchBaseDomain = "dc=nd,dc=gov"
}
'ndcloud.gov' {
$SearchBaseDomain = "dc=ndcloud,dc=gov"
}
}
### Shared-PeopleSoft-HigherEd is not found because of the extra space character in the OU name
### commented out section below is the original code, swapped out for new code 2025/01/13
# Determine if the AppName has a dedicated OU, and pick it... or choose the All-General OU
If ($DomainName -eq 'nd.gov') {
$OUAppName = Get-ADOrganizationalUnit -Server $DomainName -SearchBase ("OU=Windows,OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq $AppName }
If ($null -eq $OUAppName) {
Write-Verbose -Message "Dedicated AppName OU not found, placing in All-General OU"
$OUAppName = Get-ADOrganizationalUnit -Server $DomainName -SearchBase ("OU=Windows,OU=SERVERS,ou=COMPUTERS,ou=ITD," + $SearchBaseDomain) -Filter { Name -eq "All-General" }
}
# Determine if the Environment sub-ou is special for the selected AppName
switch ($OUAppName.Name) {
'Shared-PeopleSoft-HigherEd' {
switch ($VMEnvironment) {
'Test' { $EnvString = "Non-Prod" }
'Production' { $EnvString = "Prod" }
}
}
'Shared-PeopleSoft-State' {
switch ($VMEnvironment) {
'Test' { $EnvString = "Non-Prod" }
'Production' { $EnvString = "Prod" }
}
}
Default {
switch ($VMEnvironment) {
'Test' { $EnvString = "Test" }
'Production' { $EnvString = "Prod" }
}
}
}
# Gather all sub OUs for the AppName OU
$SubOUs = Get-ADOrganizationalUnit -Server $DomainName -SearchBase $OUAppName -Filter *
If (@($SubOUs).count -eq 1) {
$OUToUse = $SubOUs
}
Else {
$OUToUse = $SubOUs | Where-Object { $_.DistinguishedName -like ("OU=$EnvString,OU=" + $OUAppName.Name + "*") }
}
# Determine if AD Computer object already exists
$ExistingADComputer = Get-ADComputer -Filter { Name -eq $HostName }
If ($ExistingADComputer) {
Write-Verbose -Message "AD Object already exists in AD"
# Determine if AD Computer object is in the correct OU, or a sub-OU of the correct OU
If ($ExistingADComputer.DistinguishedName -like ("*" + $OUToUse.DistinguishedName)) {
Write-Verbose -Message "AD Object is in the correct OU, will attempt domain join"
$AttemptDomainJoin = $true
}
Else {
Write-Verbose -Message "AD Object is NOT in the correct OU, domain join will not occur, needs human review"
$AttemptDomainJoin = $false
}
}
Else {
$AttemptDomainJoin = $true
}
If ($AttemptDomainJoin) {
$OuFinal = $OUToUse.DistinguishedName
$FirstScriptBlock = { $DomainJoinCred = New-Object System.Management.Automation.PSCredential('svcitdvmdomainjoin', ('hypes-Vgv8h89' | ConvertTo-SecureString -AsPlainText -Force)) }
$SecondScriptText = 'Add-Computer -DomainName <DomainName> -OUPath "<OuPath>" -Credential $DomainJoinCred -Server itddc42.nd.gov'
$SecondScriptText = $SecondScriptText -replace '<DomainName>', $DomainName
$SecondScriptText = $SecondScriptText -replace '<OuPath>', $OuFinal
Write-Verbose -Message "[$FQDN]:Invoke-VMScript to AD join"
$InvokeVMScriptFunc = [System.Management.Automation.ScriptBlock]::Create("$FirstScriptBlock ; $SecondScriptText")
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialBB -ScriptType PowerShell -ScriptText $InvokeVMScriptFunc
Write-Warning -Message "[$FQDN]:Restart VMGuest, wait for Tools, then 90 seconds after"
Get-VM -Name $FQDN | Restart-VMGuest -Confirm:$false
Wait-Tools -VM (Get-VM -Name $FQDN)
Start-Sleep -Seconds 90
}
}
else {
$GuestCredentialAB = $GuestCredentialBB
}
<#
Write-Verbose -Message ("[$FQDN]:Copying SCCM client installer to C:\temp... " + (Get-Date))
Copy-VMGuestFile -Source C:\SCCM_Client\ -Destination C:\temp\SCCM_Client -VM (Get-VM -Name $FQDN) -LocalToGuest -GuestCredential $GuestCredentialAB -Force
Write-Verbose -Message ("[$FQDN]:SCCM client copy complete " + (Get-Date))
#E:\AutoBuild\SCCM_Client\
# Check if SCCM automatically installed the SCCM client and registered it
$CcmRegistered = $false
$CcmRegistration = Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
Get-Content C:\windows\ccm\logs\ClientIDManagerStartup.log
}
If ($CcmRegistration.ScriptOutput -match "Client is registered") {
Write-Warning "Client is registered."
$CcmRegistered = $true
}
ElseIf ($CcmRegistration.ScriptOutput -match "Client is already registered") {
Write-Warning "Client is already registered."
$CcmRegistered = $true
}
If ($CcmRegistered -eq $false) {
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
If (Get-Process -Name ccmsetup -ErrorAction SilentlyContinue) {
Write-Warning "CCM client is already installing"
$CcmRegistered = $true
}
ElseIf (Get-Process -Name ccmexec -ErrorAction SilentlyContinue) {
Write-Warning "CCM client is already installed"
$CcmRegistered = $true
}
Else {
Write-Warning -Message "Installing SCCM Client..."
Invoke-Expression -Command "C:\temp\SCCM_Client\ccmsetup.exe SMSSITECODE=ITD SMSMP=itdsccmp2.nd.gov DNSSUFFIX=nd.gov"
}
}
}
Write-Verbose -Message "[$FQDN]:Register SCCM Client"
While ($CcmRegistered -eq $false) {
$CcmRegistration = Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
Get-Content C:\windows\ccm\logs\ClientIDManagerStartup.log
}
If ($CcmRegistration.ScriptOutput -match "Client is registered") {
Write-Warning "Client is registered."
$CcmRegistered = $true
}
ElseIf ($CcmRegistration.ScriptOutput -match "Client is already registered") {
Write-Warning "Client is already registered."
$CcmRegistered = $true
}
ElseIf ($CcmRegistered -eq $false) { Start-Sleep -Seconds 30 }
}
Write-Verbose -Message "[$FQDN]:Approve SCCM Client"
#Start-Sleep -Seconds 30 # ADD LOOP/SMARTS TO WAIT FOR DISCOVERY AND ANOTHER FOR APPROVAL
Invoke-Command -ComputerName itdsccmp2.nd.gov -Credential $Credential -ArgumentList $Hostname -ScriptBlock {
Import-Module 'D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
$PSDrives = Get-PSDrive
If ($PSDrives | Where-Object Name -EQ "ITD") {
# ITD Drive exists, do nothing
}
else {
New-PSDrive -Name "ITD" -PSProvider AdminUI.PS.Provider\CMSite -Root itdsccmp2.nd.gov
}
Set-Location ITD:\
$Device = Get-CMDevice -Name $args[0]
If ($Device.IsApproved -eq 0) {
Approve-CMDevice -DeviceName $args[0]
}
}
Write-Verbose -Message "Trigger SCCM MachinePolicy First Check-in"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
[void] ([wmiclass] "\\localhost\root\ccm:SMS_Client").TriggerSchedule("{00000000-0000-0000-0000-000000000021}");
}
Write-Verbose -Message "Trigger SCCM MachinePolicy"
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
[void] ([wmiclass] "\\localhost\root\ccm:SMS_Client").TriggerSchedule("{00000000-0000-0000-0000-000000000021}");
}
<#Write-Verbose -Message "Waiting for network connectivity / Then KVM Activation..."
Get-VM -Name $FQDN | Invoke-VMScript -GuestCredential $GuestCredentialAB -ScriptType PowerShell -ScriptText {
# Pause until network connectivity is available
$KMS = 'kms.nd.gov'
try {
$nwJob = Start-Job -Name 'NetworkCheck' -ScriptBlock {
Param ( [String]$KMS )
do {
$nwStatus = Test-NetConnection -ComputerName $KMS -Port 1688 -InformationLevel Quiet
Start-Sleep -Seconds 10
} until($nwStatus)
} -ArgumentList $KMS
# If after 30 seconds the network connection is not responding continue on
if ((Wait-Job -Job $nwJob -Timeout 30).State -eq 'Completed') {
Write-Verbose -Message 'Network connectivity has been verified.'
}
else {
[void](Stop-Job -Job $nwJob)
Write-Verbose -Message 'Network connectivity could not be verified.'
}
}
catch {
Throw $_
Break
}
Activate via KMS
Write-Verbose -Message "Activating windows against $KMS..."
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit
}
try {
cscript C:\Windows\System32\slmgr.vbs /skms $KMS | Out-Null
cscript C:\Windows\System32\slmgr.vbs /ato | Out-Null
Write-Verbose -Message "Checking activation status..."
$kmsOut = cscript C:\Windows\System32\slmgr.vbs /dli
if (($kmsOut | Select-String -Pattern '^License Status:') -match 'Licensed') {
Write-Verbose -Message "Windows successfully activated."
}
else {
Write-Verbose -Message "Windows failed to activate, run slmgr commands manually. Ensure server time is correct."
Write-Warning -Message "Windows failed to activate, run slmgr commands manually. Ensure server time is correct."
}
}
catch {
Throw $_
Break
}
}
#>
Write-Verbose -Message ("[$FQDN]:Add to Solarwinds")
$Func = {
param($C)
Import-Module -Name ITDSolarwinds -Verbose
Import-SWDiscovery -ComputerName $C -Integration ServiceNow
}
Invoke-Command -ComputerName itdslrwnds.nd.gov -ScriptBlock $Func -ArgumentList $FQDN -Credential $Credential
Write-Verbose -Message "[$FQDN]:End"
}
end {
}
}