aim-web2.1.0rc9
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
Write-Host 'Configuring WinRM for Ansible...'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Configuration
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
$certificateFriendlyName = 'WinRM'
|
||||
$firewallRuleName = 'Windows Remote Management (HTTPS-In)'
|
||||
|
||||
# Optional additional DNS names or IP addresses, e.g. NAT / bitconnect addresses.
|
||||
$additionalSANs = @(
|
||||
# '192.168.100.10'
|
||||
# 'server.example.lan'
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Enable WinRM
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Write-Host 'Enabling WinRM...'
|
||||
winrm quickconfig -quiet
|
||||
Set-Service -Name WinRM -StartupType Automatic
|
||||
if ((Get-Service -Name WinRM).Status -ne 'Running') {
|
||||
Start-Service -Name WinRM
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Determine host names and IP addresses
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
$hostName = $env:COMPUTERNAME
|
||||
$computerSystem = Get-CimInstance Win32_ComputerSystem
|
||||
$domain = $computerSystem.Domain
|
||||
|
||||
$hostIPs = @(
|
||||
Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue |
|
||||
Where-Object {
|
||||
$_.IPAddress -notlike '127.*' -and
|
||||
$_.IPAddress -notlike '169.254.*'
|
||||
} |
|
||||
Select-Object -ExpandProperty IPAddress -Unique
|
||||
)
|
||||
|
||||
if (-not $hostIPs) {
|
||||
throw 'No usable IPv4 address found for WinRM certificate creation.'
|
||||
}
|
||||
|
||||
$certificateNames = @($hostName)
|
||||
if ($computerSystem.PartOfDomain -and -not [string]::IsNullOrWhiteSpace($domain)) {
|
||||
$certificateNames += "$hostName.$domain"
|
||||
}
|
||||
$certificateNames += $hostIPs
|
||||
$certificateNames += $additionalSANs
|
||||
$certificateNames = @(
|
||||
$certificateNames |
|
||||
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
|
||||
Select-Object -Unique
|
||||
)
|
||||
|
||||
Write-Host 'Certificate SANs:'
|
||||
$certificateNames | ForEach-Object { Write-Host " - $_" }
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Find or create WinRM certificate
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
$cert = Get-ChildItem 'Cert:\LocalMachine\My' |
|
||||
Where-Object {
|
||||
$_.FriendlyName -eq $certificateFriendlyName -and
|
||||
$_.NotAfter -gt (Get-Date).AddDays(30)
|
||||
} |
|
||||
Sort-Object NotAfter -Descending |
|
||||
Select-Object -First 1
|
||||
|
||||
if (-not $cert) {
|
||||
Write-Host 'Creating self-signed WinRM certificate...'
|
||||
|
||||
$certCommand = Get-Command New-SelfSignedCertificate -ErrorAction Stop
|
||||
$certParams = @{ DnsName = $certificateNames }
|
||||
|
||||
if ($certCommand.Parameters.ContainsKey('CertStoreLocation')) {
|
||||
$certParams['CertStoreLocation'] = 'Cert:\LocalMachine\My'
|
||||
}
|
||||
if ($certCommand.Parameters.ContainsKey('FriendlyName')) {
|
||||
$certParams['FriendlyName'] = $certificateFriendlyName
|
||||
}
|
||||
if ($certCommand.Parameters.ContainsKey('TextExtension')) {
|
||||
$certParams['TextExtension'] = '2.5.29.37={text}1.3.6.1.5.5.7.3.1'
|
||||
}
|
||||
|
||||
try {
|
||||
$cert = New-SelfSignedCertificate @certParams
|
||||
}
|
||||
catch {
|
||||
if ($_.CategoryInfo.Reason -ne 'InvalidStorePathException' -or -not $certParams.ContainsKey('CertStoreLocation')) {
|
||||
throw
|
||||
}
|
||||
|
||||
# Windows Server 2012 R2 / PowerShell 4 can expose CertStoreLocation but
|
||||
# reject the valid Cert:\LocalMachine\My argument. The compatibility
|
||||
# path is to run the cmdlet while the certificate provider is in that store.
|
||||
Write-Host 'Legacy certificate-store behavior detected; retrying in compatibility mode.'
|
||||
$certParams.Remove('CertStoreLocation')
|
||||
Push-Location 'Cert:\LocalMachine\My'
|
||||
try {
|
||||
$cert = New-SelfSignedCertificate @certParams
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
if ($cert.FriendlyName -ne $certificateFriendlyName) {
|
||||
try {
|
||||
$cert.FriendlyName = $certificateFriendlyName
|
||||
}
|
||||
catch {
|
||||
Write-Warning 'Certificate was created, but its friendly name could not be set. Future runs may create a replacement certificate.'
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Host 'Existing WinRM certificate found.'
|
||||
}
|
||||
|
||||
if (-not $cert.Thumbprint) {
|
||||
throw 'WinRM certificate does not contain a valid thumbprint.'
|
||||
}
|
||||
Write-Host "Certificate thumbprint: $($cert.Thumbprint)"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Configure HTTPS listener
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
$httpsListener = Get-ChildItem WSMan:\localhost\Listener |
|
||||
Where-Object { $_.Keys -contains 'Transport=HTTPS' } |
|
||||
Select-Object -First 1
|
||||
|
||||
if (-not $httpsListener) {
|
||||
Write-Host 'Creating WinRM HTTPS listener...'
|
||||
New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $cert.Thumbprint -Force | Out-Null
|
||||
}
|
||||
else {
|
||||
Write-Host 'WinRM HTTPS listener already exists.'
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Configure firewall
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
$firewallRule = Get-NetFirewallRule -DisplayName $firewallRuleName -ErrorAction SilentlyContinue
|
||||
if (-not $firewallRule) {
|
||||
Write-Host 'Creating WinRM HTTPS firewall rule...'
|
||||
New-NetFirewallRule -DisplayName $firewallRuleName -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow -Program System | Out-Null
|
||||
}
|
||||
else {
|
||||
Write-Host 'WinRM HTTPS firewall rule already exists.'
|
||||
Enable-NetFirewallRule -DisplayName $firewallRuleName | Out-Null
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Non-domain systems
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if (-not $computerSystem.PartOfDomain) {
|
||||
Write-Host 'Non-domain system detected.'
|
||||
Write-Host 'Enabling remote administrative token for local accounts...'
|
||||
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' -Name 'LocalAccountTokenFilterPolicy' -PropertyType DWord -Value 1 -Force | Out-Null
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Verification
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'Verifying WinRM configuration...'
|
||||
|
||||
$listener = Get-ChildItem WSMan:\localhost\Listener |
|
||||
Where-Object { $_.Keys -contains 'Transport=HTTPS' } |
|
||||
Select-Object -First 1
|
||||
if (-not $listener) {
|
||||
throw 'WinRM HTTPS listener verification failed.'
|
||||
}
|
||||
|
||||
$firewallRule = Get-NetFirewallRule -DisplayName $firewallRuleName -ErrorAction SilentlyContinue
|
||||
if (-not $firewallRule) {
|
||||
throw 'WinRM firewall rule verification failed.'
|
||||
}
|
||||
if ((Get-Service WinRM).Status -ne 'Running') {
|
||||
throw 'WinRM service is not running.'
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'WinRM configuration completed successfully.'
|
||||
Write-Host 'HTTPS port: 5986'
|
||||
Write-Host "Certificate: $($cert.Thumbprint)"
|
||||
Reference in New Issue
Block a user