<# NFA Installer - v2021.18 Scripted install for AutoCert to DC0x and all domain members. This script is to be executed as Domain Admin. This will enumerate all servers in the domain, and attempt to install AutoCert on those that would have certificates to replace - can optionally choose to not replace certificates if not needed. - Special install for PRX (not domain member) - No installs for FS0x, RDSCLx, WVDx servers #> # User running script should be domain admin function DomainAdminCheck { if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Domain Admins")) { Write-Host "Account used to run Powershell is a domain admin, continuing replacement" } else { Write-Host "Account used to run Powershell is NOT a Domain Administrator, exiting script..." pause exit } } DomainAdminCheck # Set Tls1.2 to download files from Azure [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Enumerate list of VMs in domain Import-Module ActiveDirectory if (!(Get-Module ActiveDirectory)) { Write-Host "ActiveDirectory module not installed - please run install script on DC01." pause exit } Write-Host "Checking for Domain Servers..." $ServerArray = @('DC0*', "RDSH*", "RDGW*", "RDSCB*", "WS*", "FS*") $DomainServerArray = @() foreach ($server in $ServerArray){ $DomainServer = Get-ADComputer -filter {Name -like $server} | Select-Object Name $DomainServerArray += $DomainServer.name if ($domainserver){ Write-Host "$($domainserver.name) found. Will attempt replacement procedure." -Foregroundcolor white -Backgroundcolor Green } else { $ServerType = $server.replace("*","") Write-Host "No $ServerType servers found. Certificate replacement will NOT be run for this server type." -Foregroundcolor white -Backgroundcolor Red } } # Iterate through each server found foreach ($domainserver in $DomainServerArray) { # DC Task/ExpiryCheck Install if ($domainserver -like "DC0*") { Write-Host "$domainserver is a DC server" $ValidPing = Test-NetConnection -ComputerName $domainserver -CommonTCPPort WINRM -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $serverAvailable = $false if ($validPing.TcpTestSucceeded) { $ErrorActionPreference = 'Stop' try { $serverAvailable = [System.Net.Dns]::GetHostEntry($ValidPing.RemoteAddress.IPAddressToString).HostName -match $domainserver } catch [System.Management.Automation.MethodInvocationException] { # No reverse DNS zone, assume DNS is correct if ($_.Exception -match 'No such host is known') { $serverAvailable = $true } } $ErrorActionPreference = 'Continue' } if ($ValidPing.TcpTestSucceeded -and $serverAvailable) { Write-Host ("$domainserver is reachable, continuing replacement.") Invoke-Command -Computername "$domainserver" -ScriptBlock { # Set Tls1.2 to download files from Azure [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $CurrentServer = $env:computername Write-Host "Current computer name is $CurrentServer. This Certificate Package is meant for Domain Controllers ONLY. Would you like to proceed?" $ReadHost = Read-host "(y/n)" $response = $false Switch ($ReadHost) { Y {Write-Host "You chose YES. Continuing with Domain Controller Automatic Certificate Replacement" -Foregroundcolor white -Backgroundcolor Green;$response=$true} N {Write-Host "You chose NO. Exiting Domain Controller Automatic Certificate Replacement script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;break} Default {Write-Host "No option chosen for $CurrentServer. Exiting Script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;break} } if ($response) { # Variable Assignment $DC_ExpiryCheck_URL = "https://nfaurls.azurewebsites.net/DC-Expiration" $AutoCert_Task_URL ="https://nfaurls.azurewebsites.net/AutoCert-Task" $ExpiryCheck_Path = "c:\AutoCert\ExpiryCheck.ps1" $Task_XML_Path = "c:\AutoCert\AutoCert.xml" # Install AutoCert New-Item -ItemType directory -Path c:\AutoCert -erroraction SilentlyContinue | out-null Invoke-WebRequest -Uri $AutoCert_Task_URL -outfile $Task_XML_Path Invoke-WebRequest -Uri $DC_ExpiryCheck_URL -outfile $ExpiryCheck_Path Unregister-ScheduledTask -TaskName "CertificateReplacement" -Confirm:$false -erroraction SilentlyContinue Schtasks /create /xml "c:\AutoCert\AutoCert.xml" /tn CertificateReplacement /ru SYSTEM Start-ScheduledTask -TaskName "CertificateReplacement" Remove-Item $Task_XML_Path } } } else { Write-Host ("$domainserver can NOT be reached.") -Foregroundcolor White -Backgroundcolor Red pause } } # RDP Task/ExpiryCheck Install if ($domainserver -like "RDSH*" -or $domainserver -like "WS*" -or $domainserver -like "FS*") { Write-Host "$domainserver - attempting to replace Remote Desktop (RDP-TCP) certificate." $ValidPing = Test-NetConnection -ComputerName $domainserver -CommonTCPPort WINRM -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $serverAvailable = $false if ($validPing.TcpTestSucceeded) { $ErrorActionPreference = 'Stop' try { $serverAvailable = [System.Net.Dns]::GetHostEntry($ValidPing.RemoteAddress.IPAddressToString).HostName -match $domainserver } catch [System.Management.Automation.MethodInvocationException] { # No reverse DNS zone, assume DNS is correct if ($_.Exception -match 'No such host is known') { $serverAvailable = $true } } $ErrorActionPreference = 'Continue' } if ($ValidPing.TcpTestSucceeded -and $serverAvailable) { Write-Host ("$domainserver is reachable, continuing replacement.") Invoke-Command -ComputerName "$domainserver" -ScriptBlock { # Set Tls1.2 to download files from Azure [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $CurrentServer = $env:computername Write-Host "The current server is $CurrentServer. This Certificate Package will replace Remote Desktop (RDP) certificates ONLY. Would you like to proceed?" $ReadHost = Read-host "(y/n)" $response = $false Switch ($ReadHost) { Y {Write-Host "You chose YES. Continuing with RDP Automatic Certificate Replacement" -Foregroundcolor white -Backgroundcolor Green;$response=$true} N {Write-Host "You chose NO. Exiting RDP Automatic Certificate Replacement script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;exit} Default {Write-Host "No option chosen for $CurrentServer. Exiting Script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;exit} } if ($response) { # Variable Assignment $RDS_ExpiryCheck_URL = "https://nfaurls.azurewebsites.net/RDSH-Expiration" $AutoCert_Task_URL ="https://nfaurls.azurewebsites.net/AutoCert-Task" $ExpiryCheck_Path = "c:\AutoCert\ExpiryCheck.ps1" $Task_XML_Path = "c:\AutoCert\AutoCert.xml" # Install AutoCert New-Item -ItemType directory -Path c:\AutoCert -erroraction SilentlyContinue | out-null Invoke-WebRequest -Uri $AutoCert_Task_URL -outfile $Task_XML_Path Invoke-WebRequest -Uri $RDS_ExpiryCheck_URL -outfile $ExpiryCheck_Path Unregister-ScheduledTask -TaskName "CertificateReplacement" -Confirm:$false -erroraction SilentlyContinue Schtasks /create /xml "c:\AutoCert\AutoCert.xml" /tn CertificateReplacement /ru SYSTEM Start-ScheduledTask -TaskName "CertificateReplacement" Remove-Item $Task_XML_Path } } } else { Write-Host ("$domainserver can NOT be reached. Please run the Install_RDS_AutoCert.ps1 script on the server, when available.") -Foregroundcolor White -Backgroundcolor Red pause } } # RDGW Task/ExpiryCheck Install if ($domainserver -like "RDGW*") { Write-Host "$domainserver is a RDGW server" $ValidPing = Test-NetConnection -ComputerName $domainserver -CommonTCPPort WINRM -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $serverAvailable = $false if ($validPing.TcpTestSucceeded) { $ErrorActionPreference = 'Stop' try { $serverAvailable = [System.Net.Dns]::GetHostEntry($ValidPing.RemoteAddress.IPAddressToString).HostName -match $domainserver } catch [System.Management.Automation.MethodInvocationException] { # No reverse DNS zone, assume DNS is correct if ($_.Exception -match 'No such host is known') { $serverAvailable = $true } } $ErrorActionPreference = 'Continue' } if ($ValidPing.TcpTestSucceeded -and $serverAvailable) { Write-Host ("$domainserver is reachable, continuing replacement.") Invoke-Command -computername "$domainserver" -Scriptblock { # Set Tls1.2 to download files from Azure [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $CurrentServer = $env:computername Write-Host "The current server being updated is $CurrentServer. This Certificate Package is meant for RDGW servers ONLY. Would you like to proceed?" $ReadHost = Read-host "(y/n)" $response = $false Switch ($ReadHost) { Y {Write-Host "You chose YES. Continuing with RD Gateway Automatic Certificate Replacement" -Foregroundcolor white -Backgroundcolor Green;$response=$true} N {Write-Host "You chose NO. Exiting RD Gateway Automatic Certificate Replacement script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;exit} Default {Write-Host "No option chosen for $CurrentServer. Exiting Script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;exit} } if ($response) { # Variable Assignment $RDGW_ExpiryCheck_URL = "https://nfaurls.azurewebsites.net/RDGW-Expiration" $AutoCert_Task_URL ="https://nfaurls.azurewebsites.net/AutoCert-Task" $ExpiryCheck_Path = "c:\AutoCert\ExpiryCheck.ps1" $Task_XML_Path = "c:\AutoCert\AutoCert.xml" # Install AutoCert New-Item -ItemType directory -Path c:\AutoCert -erroraction SilentlyContinue | out-null Invoke-WebRequest -Uri $AutoCert_Task_URL -outfile $Task_XML_Path Invoke-WebRequest -Uri $RDGW_ExpiryCheck_URL -outfile $ExpiryCheck_Path Unregister-ScheduledTask -TaskName "CertificateReplacement" -Confirm:$false -erroraction SilentlyContinue Schtasks /create /xml "c:\AutoCert\AutoCert.xml" /tn CertificateReplacement /ru SYSTEM Start-ScheduledTask -TaskName "CertificateReplacement" Remove-Item $Task_XML_Path } } } else { Write-Host ("$domainserver can NOT be reached. Please run the Install_RDGW_AutoCert.ps1 script on the server, when available.") -Foregroundcolor White -Backgroundcolor Red pause } } # RDSCB Task/ExpiryCheck Install if ($domainserver -like "RDSCB*"){ Write-Host "$domainserver is a RDSCB server" $ValidPing = Test-NetConnection -ComputerName $domainserver -CommonTCPPort WINRM -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $serverAvailable = $false if ($validPing.TcpTestSucceeded) { $ErrorActionPreference = 'Stop' try { $serverAvailable = [System.Net.Dns]::GetHostEntry($ValidPing.RemoteAddress.IPAddressToString).HostName -match $domainserver } catch [System.Management.Automation.MethodInvocationException] { # No reverse DNS zone, assume DNS is correct if ($_.Exception -match 'No such host is known') { $serverAvailable = $true } } $ErrorActionPreference = 'Continue' } if ($ValidPing.TcpTestSucceeded -and $serverAvailable) { Write-Host ("$domainserver is reachable, continuing replacement.") Invoke-Command -computername "$domainserver" -Scriptblock { # Set Tls1.2 to download files from Azure [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $CurrentServer = $env:computername Write-Host "The current server being updated is $CurrentServer. This Certificate Package is meant for RDSCB servers ONLY. Would you like to proceed?" $ReadHost = Read-host "(y/n)" $response = $false Switch ($ReadHost) { Y {Write-Host "You chose YES. Continuing with RDSCB Automatic Certificate Replacement" -Foregroundcolor white -Backgroundcolor Green;$response=$true} N {Write-Host "You chose NO. Exiting RDSCB Automatic Certificate Replacement script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;exit} Default {Write-Host "No option chosen for $CurrentServer. Exiting Script without making configuration changes."-Foregroundcolor white -Backgroundcolor Red;pause;exit} } if ($response) { # Variable Assignment $RDS_ExpiryCheck_URL = "https://nfaurls.azurewebsites.net/RDSCB-Expiration" $ExpiryCheck_Path = "c:\AutoCert\ExpiryCheck.ps1" $AutoCert_Task_URL ="https://nfaurls.azurewebsites.net/AutoCert-Task" $Task_XML_Path = "c:\AutoCert\AutoCert.xml" # Install AutoCert New-Item -ItemType directory -Path c:\AutoCert -erroraction SilentlyContinue | out-null Invoke-WebRequest -Uri $AutoCert_Task_URL -outfile $Task_XML_Path Invoke-WebRequest -Uri $RDS_ExpiryCheck_URL -outfile $ExpiryCheck_Path Unregister-ScheduledTask -TaskName "CertificateReplacement" -Confirm:$false -erroraction SilentlyContinue Schtasks /create /xml "c:\AutoCert\AutoCert.xml" /tn CertificateReplacement /ru SYSTEM Start-ScheduledTask -TaskName "CertificateReplacement" Remove-Item $Task_XML_Path } } } else { Write-Host ("$domainserver can NOT be reached. Please run the Install_RDSCB_AutoCert.ps1 script on the server, when available.") -Foregroundcolor White -Backgroundcolor Red pause } } } # Iterate through trusted domains Write-Host "Checking for Trusted Domain..." $TrustDomains = Get-ADTrust -filter * $TrustedServerArray = @("RDSH*","WS*") if (!$TrustDomains) { Write-Host "No domain trust found. Skipping check for trusted domain machines." -Foregroundcolor White -Backgroundcolor Red pause exit } foreach ($domain in $TrustDomains) { # Get domain admin credentials Write-Host "Found domain trust for $($domain.name). Checking for RDSH servers and workstations." -Foregroundcolor white -Backgroundcolor Green Write-Host "Please enter $($domain.name) Domain Admin credentials to continue with replacement in $($domain.name):" $TrustCreds = Get-Credential # Enumerate list of VMs in each trusted domain $TrustedDomainServerArray = @() foreach ($server in $TrustedServerArray) { $TrustedDomainServer = Get-ADComputer -filter {Name -like $server} -Server $Domain.name foreach ($computerObject in $TrustedDomainServer) { $ErrorActionPreference = "Stop" try { Write-Host "$($computerObject.DNShostname) found, testing connectivity..." -Foregroundcolor Black -Backgroundcolor Yellow Invoke-Command -computername $computerObject.DNSHostName -credential $TrustCreds -Scriptblock ${function:DomainAdminCheck} Write-Host "$($computerObject.DNShostname) success. Marked for replacement procedure." -Foregroundcolor Black -Backgroundcolor Green $TrustedDomainServerArray += $computerObject.DNSHostName } catch { Write-Host "$($computerObject.DNShostname) not accessible, please run the Install_RDS_AutoCert.ps1 script on the machine directly." -Foregroundcolor Black -Backgroundcolor Yellow } $ErrorActionPreference = "Continue" } } # Iterate through each server found foreach ($domainserver in $TrustedDomainServerArray) { Write-Host ("$domainserver is reachable, continuing replacement with provided credentials.") Invoke-Command -Computername "$domainserver" -Credential $TrustCreds -ScriptBlock { # Set Tls1.2 to download files from Azure [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $CurrentServer = $env:computername Write-Host "The current server being updated is $CurrentServer. This Certificate Package will replace Remote Desktop (RDP) certificates ONLY. Would you like to proceed?" $ReadHost = Read-host "(y/n)" $response = $false Switch ($ReadHost) { Y {Write-Host "You chose YES. Continuing with RDP Automatic Certificate Replacement" -Foregroundcolor Black -Backgroundcolor Green;$response=$true} N {Write-Host "You chose NO. Exiting RDP Automatic Certificate Replacement script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;exit} Default {Write-Host "No option chosen for $CurrentServer. Exiting Script without making configuration changes." -Foregroundcolor white -Backgroundcolor Red;pause;exit} } if ($response) { # Variable Assignment $RDS_ExpiryCheck_URL = "https://nfaurls.azurewebsites.net/RDSH-Expiration" $AutoCert_Task_URL ="https://nfaurls.azurewebsites.net/AutoCert-Task" $ExpiryCheck_Path = "c:\AutoCert\ExpiryCheck.ps1" $Task_XML_Path = "c:\AutoCert\AutoCert.xml" # Install AutoCert New-Item -ItemType directory -Path c:\AutoCert -erroraction SilentlyContinue | out-null Invoke-WebRequest -Uri $AutoCert_Task_URL -outfile $Task_XML_Path Invoke-WebRequest -Uri $RDS_ExpiryCheck_URL -outfile $ExpiryCheck_Path Unregister-ScheduledTask -TaskName "CertificateReplacement" -Confirm:$false -erroraction SilentlyContinue Schtasks /create /xml "c:\AutoCert\AutoCert.xml" /tn CertificateReplacement /ru SYSTEM Start-ScheduledTask -TaskName "CertificateReplacement" Remove-Item $Task_XML_Path } } } }