@ -5,26 +5,33 @@
# necessary changes to allow Ansible to connect, authenticate and execute
# necessary changes to allow Ansible to connect, authenticate and execute
# PowerShell commands.
# PowerShell commands.
#
#
# Set $VerbosePreference = "Continue" before running the script in order to
# All events are logged to the Windows EventLog, useful for unattended runs.
# see the output messages.
# Set $SkipNetworkProfileCheck to skip the network profile check. Without
# specifying this the script will only run if the device's interfaces are in
# DOMAIN or PRIVATE zones. Provide this switch if you want to enable winrm on
# a device with an interface in PUBLIC zone.
#
#
# Set $ForceNewSSLCert if the system has been syspreped and a new SSL Cert
# Use option -Verbose in order to see the verbose output messages.
# must be forced on the WinRM Listener when re-running this script. This
#
# is necessary when a new SID and CN name is created.
# Use option -SkipNetworkProfileCheck to skip the network profile check.
# Without specifying this the script will only run if the device's interfaces
# are in DOMAIN or PRIVATE zones. Provide this switch if you want to enable
# WinRM on a device with an interface in PUBLIC zone.
#
# Use option -ForceNewSSLCert if the system has been SysPreped and a new
# SSL Certifcate must be forced on the WinRM Listener when re-running this
# script. This is necessary when a new SID and CN name is created.
#
#
# Written by Trond Hindenes <trond@hindenes.com>
# Written by Trond Hindenes <trond@hindenes.com>
# Updated by Chris Church <cchurch@ansible.com>
# Updated by Chris Church <cchurch@ansible.com>
# Updated by Michael Crilly <mike@autologic.cm>
# Updated by Michael Crilly <mike@autologic.cm>
# Updated by Anton Ouzounov <Anton.Ouzounov@careerbuilder.com>
# Updated by Anton Ouzounov <Anton.Ouzounov@careerbuilder.com>
# Updated by Dag Wieërs <dag@wieers.com>
#
#
# Version 1.0 - July 6th, 2014
# Version 1.0 - 2014-07-06
# Version 1.1 - November 11th, 2014
# Version 1.1 - 2014-11-11
# Version 1.2 - May 15th, 2015
# Version 1.2 - 2015-05-15
# Version 1.3 - April 4th, 2016
# Version 1.3 - 2016-04-04
# Version 1.4 - 2017-01-05
# Support -Verbose option
[ CmdletBinding ( ) ]
Param (
Param (
[ string ] $SubjectName = $env:COMPUTERNAME ,
[ string ] $SubjectName = $env:COMPUTERNAME ,
@ -34,6 +41,26 @@ Param (
[ switch ] $ForceNewSSLCert
[ switch ] $ForceNewSSLCert
)
)
Function Write-Log
{
$Message = $args [ 0 ]
Write-EventLog -LogName Application -Source $EventSource -EntryType Information -EventId 1 -Message $Message
}
Function Write-VerboseLog
{
$Message = $args [ 0 ]
Write-Verbose $Message
Write-Log $Message
}
Function Write-HostLog
{
$Message = $args [ 0 ]
Write-Host $Message
Write-Log $Message
}
Function New-LegacySelfSignedCert
Function New-LegacySelfSignedCert
{
{
Param (
Param (
@ -86,10 +113,21 @@ Trap
Exit 1
Exit 1
}
}
$ErrorActionPreference = " Stop "
$ErrorActionPreference = " Stop "
$EventSource = $MyInvocation . MyCommand . Name
If ( $EventSource -eq $Null )
{
$EventSource = " Powershell CLI "
}
If ( [ System.Diagnostics.EventLog ] :: Exists ( 'Application' ) -eq $False -or [ System.Diagnostics.EventLog ] :: SourceExists ( $EventSource ) -eq $False )
{
New-EventLog -LogName Application -Source $EventSource
}
# Detect PowerShell version.
# Detect PowerShell version.
If ( $PSVersionTable . PSVersion . Major -lt 3 )
If ( $PSVersionTable . PSVersion . Major -lt 3 )
{
{
Write-Log " PowerShell version 3 or higher is required. "
Throw " PowerShell version 3 or higher is required. "
Throw " PowerShell version 3 or higher is required. "
}
}
@ -97,26 +135,32 @@ If ($PSVersionTable.PSVersion.Major -lt 3)
Write-Verbose " Verifying WinRM service. "
Write-Verbose " Verifying WinRM service. "
If ( ! ( Get-Service " WinRM " ) )
If ( ! ( Get-Service " WinRM " ) )
{
{
Write-Log " Unable to find the WinRM service. "
Throw " Unable to find the WinRM service. "
Throw " Unable to find the WinRM service. "
}
}
ElseIf ( ( Get-Service " WinRM " ) . Status -ne " Running " )
ElseIf ( ( Get-Service " WinRM " ) . Status -ne " Running " )
{
{
Write-Verbose " Starting WinRM service. "
Write-Verbose " Starting WinRM service. "
Start-Service -Name " WinRM " -ErrorAction Stop
Start-Service -Name " WinRM " -ErrorAction Stop
Write-Log " Started WinRM service. "
Write-Verbose " Setting WinRM service to start automatically on boot. "
Write-Verbose " Setting WinRM service to start automatically on boot. "
Set-Service -Name " WinRM " -StartupType Automatic
Set-Service -Name " WinRM " -StartupType Automatic
Write-Log " Set WinRM service to start automatically on boot. "
}
}
# WinRM should be running; check that we have a PS session config.
# WinRM should be running; check that we have a PS session config.
If ( ! ( Get-PSSessionConfiguration -Verbose: $false ) -or ( ! ( Get-ChildItem WSMan : \ localhost \ Listener ) ) )
If ( ! ( Get-PSSessionConfiguration -Verbose: $false ) -or ( ! ( Get-ChildItem WSMan : \ localhost \ Listener ) ) )
{
{
i f ( $SkipNetworkProfileCheck ) {
I f ( $SkipNetworkProfileCheck ) {
Write-Verbose " Enabling PS Remoting without checking Network profile. "
Write-Verbose " Enabling PS Remoting without checking Network profile. "
Enable-PSRemoting -SkipNetworkProfileCheck -Force -ErrorAction Stop
Enable-PSRemoting -SkipNetworkProfileCheck -Force -ErrorAction Stop
Write-Log " Enabled PS Remoting without checking Network profile. "
}
}
e lse {
E lse {
Write-Verbose " Enabling PS Remoting "
Write-Verbose " Enabling PS Remoting . "
Enable-PSRemoting -Force -ErrorAction Stop
Enable-PSRemoting -Force -ErrorAction Stop
Write-Log " Enabled PS Remoting. "
}
}
}
}
Else
Else
@ -133,12 +177,12 @@ If (!($listeners | Where {$_.Keys -like "TRANSPORT=HTTPS"}))
{
{
$cert = New-SelfSignedCertificate -DnsName $SubjectName -CertStoreLocation " Cert:\LocalMachine\My "
$cert = New-SelfSignedCertificate -DnsName $SubjectName -CertStoreLocation " Cert:\LocalMachine\My "
$thumbprint = $cert . Thumbprint
$thumbprint = $cert . Thumbprint
Write-Host " Self-signed SSL certificate generated; thumbprint: $thumbprint "
Write-Host Log " Self-signed SSL certificate generated; thumbprint: $thumbprint "
}
}
Else
Else
{
{
$thumbprint = New-LegacySelfSignedCert -SubjectName $SubjectName
$thumbprint = New-LegacySelfSignedCert -SubjectName $SubjectName
Write-Host " (Legacy) Self-signed SSL certificate generated; thumbprint: $thumbprint "
Write-Host Log " (Legacy) Self-signed SSL certificate generated; thumbprint: $thumbprint "
}
}
# Create the hashtables of settings to be used.
# Create the hashtables of settings to be used.
@ -152,25 +196,27 @@ If (!($listeners | Where {$_.Keys -like "TRANSPORT=HTTPS"}))
Write-Verbose " Enabling SSL listener. "
Write-Verbose " Enabling SSL listener. "
New-WSManInstance -ResourceURI 'winrm/config/Listener' -SelectorSet $selectorset -ValueSet $valueset
New-WSManInstance -ResourceURI 'winrm/config/Listener' -SelectorSet $selectorset -ValueSet $valueset
Write-Log " Enabled SSL listener. "
}
}
Else
Else
{
{
Write-Verbose " SSL listener is already active. "
Write-Verbose " SSL listener is already active. "
# Force a new SSL cert on Listener if the $ForceNewSSLCert
# Force a new SSL cert on Listener if the $ForceNewSSLCert
if ( $ForceNewSSLCert ) {
If ( $ForceNewSSLCert )
{
# Create the new cert.
# Create the new cert.
If ( Get-Command " New-SelfSignedCertificate " -ErrorAction SilentlyContinue )
If ( Get-Command " New-SelfSignedCertificate " -ErrorAction SilentlyContinue )
{
{
$cert = New-SelfSignedCertificate -DnsName $SubjectName -CertStoreLocation " Cert:\LocalMachine\My "
$cert = New-SelfSignedCertificate -DnsName $SubjectName -CertStoreLocation " Cert:\LocalMachine\My "
$thumbprint = $cert . Thumbprint
$thumbprint = $cert . Thumbprint
Write-Host " Self-signed SSL certificate generated; thumbprint: $thumbprint "
Write-Host Log " Self-signed SSL certificate generated; thumbprint: $thumbprint "
}
}
Else
Else
{
{
$thumbprint = New-LegacySelfSignedCert -SubjectName $SubjectName
$thumbprint = New-LegacySelfSignedCert -SubjectName $SubjectName
Write-Host " (Legacy) Self-signed SSL certificate generated; thumbprint: $thumbprint "
Write-Host Log " (Legacy) Self-signed SSL certificate generated; thumbprint: $thumbprint "
}
}
$valueset = @ { }
$valueset = @ { }
@ -194,6 +240,7 @@ If (($basicAuthSetting.Value) -eq $false)
{
{
Write-Verbose " Enabling basic auth support. "
Write-Verbose " Enabling basic auth support. "
Set-Item -Path " WSMan:\localhost\Service\Auth\Basic " -Value $true
Set-Item -Path " WSMan:\localhost\Service\Auth\Basic " -Value $true
Write-Log " Enabled basic auth support. "
}
}
Else
Else
{
{
@ -207,11 +254,13 @@ If ($fwtest1.count -lt 5)
{
{
Write-Verbose " Adding firewall rule to allow WinRM HTTPS. "
Write-Verbose " Adding firewall rule to allow WinRM HTTPS. "
netsh advfirewall firewall add rule profile = any name = " Allow WinRM HTTPS " dir = in localport = 5986 protocol = TCP action = allow
netsh advfirewall firewall add rule profile = any name = " Allow WinRM HTTPS " dir = in localport = 5986 protocol = TCP action = allow
Write-Log " Added firewall rule to allow WinRM HTTPS. "
}
}
ElseIf ( ( $fwtest1 . count -ge 5 ) -and ( $fwtest2 . count -lt 5 ) )
ElseIf ( ( $fwtest1 . count -ge 5 ) -and ( $fwtest2 . count -lt 5 ) )
{
{
Write-Verbose " Updating firewall rule to allow WinRM HTTPS for any profile. "
Write-Verbose " Updating firewall rule to allow WinRM HTTPS for any profile. "
netsh advfirewall firewall set rule name = " Allow WinRM HTTPS " new profile = any
netsh advfirewall firewall set rule name = " Allow WinRM HTTPS " new profile = any
Write-Log " Updated firewall rule to allow WinRM HTTPS for any profile. "
}
}
Else
Else
{
{
@ -238,6 +287,7 @@ ElseIf ($httpResult -and !$httpsResult)
}
}
Else
Else
{
{
Write-Log " Unable to establish an HTTP or HTTPS remoting session. "
Throw " Unable to establish an HTTP or HTTPS remoting session. "
Throw " Unable to establish an HTTP or HTTPS remoting session. "
}
}
Write-Verbose " PS Remoting has been successfully configured for Ansible. "
Write-Verbose Log " PS Remoting has been successfully configured for Ansible. "