ConfigureRemotingForAnsible.ps1 5.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
# Script to set a windows computer up for remoting
# The script checks the current WinRM/Remoting configuration and makes the necessary changes
# set $VerbosePreference="Continue" before running the script in order to see the output of the script
#
# Written by Trond Hindenes <trond@hindenes.com>
#
# Version 1.0 - July 6th, 2014


Param (
    [string]$SubjectName = $env:COMPUTERNAME,
    [int]$CertValidityDays = 365,
    $CreateSelfSignedCert = $true
)


#region function defs
Function New-LegacySelfSignedCert
{
    Param (
        [string]$SubjectName,
        [int]$ValidDays = 365
    )
    
    $name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
    $name.Encode("CN=$SubjectName", 0)

    $key = new-object -com "X509Enrollment.CX509PrivateKey.1"
    $key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
    $key.KeySpec = 1
    $key.Length = 1024
    $key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
    $key.MachineContext = 1
    $key.Create()

    $serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
    $serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1")
    $ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
    $ekuoids.add($serverauthoid)
    $ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
    $ekuext.InitializeEncode($ekuoids)

    $cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
    $cert.InitializeFromPrivateKey(2, $key, "")
    $cert.Subject = $name
    $cert.Issuer = $cert.Subject
    $cert.NotBefore = (get-date).addDays(-1)
    $cert.NotAfter = $cert.NotBefore.AddDays($ValidDays)
    $cert.X509Extensions.Add($ekuext)
    $cert.Encode()

    $enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
    $enrollment.InitializeFromRequest($cert)
    $certdata = $enrollment.CreateRequest(0)
    $enrollment.InstallResponse(2, $certdata, 0, "")

    #return the thumprint of the last installed cert
    ls "Cert:\LocalMachine\my"| Sort-Object notbefore -Descending | select -First 1 | select -expand Thumbprint
}

#endregion

#Start script
$ErrorActionPreference = "Stop"

#Detect PowerShell version
if ($PSVersionTable.PSVersion.Major -lt 3)
{
    Write-Error "PowerShell/Windows Management Framework needs to be updated to 3 or higher. Stopping script"
}

#Detect OS
 $Win32_OS = Get-WmiObject Win32_OperatingSystem

 switch ($Win32_OS.Version)
 {
    "6.2.9200" {$OSVersion = "Windows Server 2012"}
    "6.1.7601" {$OSVersion = "Windows Server 2008R2"}
 }


 #Set up remoting
 Write-verbose "Verifying WS-MAN"
 if (!(get-service "WinRM"))
 {
    Write-Error "I couldnt find the winRM service on this computer. Stopping"
 }
 Elseif ((get-service "WinRM").Status -ne "Running")
 {
    Write-Verbose "Starting WinRM"
    Start-Service -Name "WinRM" -ErrorAction Stop
 }

 #At this point, winrm should be running
 #Check that we have a ps session config
 if (!(Get-PSSessionConfiguration -verbose:$false) -or (!(get-childitem WSMan:\localhost\Listener)))
 {
    Write-Verbose "PS remoting is not enabled. Activating"
    try
    {
        Enable-PSRemoting -Force -ErrorAction SilentlyContinue
    }    
    catch{}
 }
 Else
 {
    Write-Verbose "PS remoting is already active and running"
 }

 #At this point, test a remoting connection to localhost, which should work
 $result = invoke-command -ComputerName localhost -ScriptBlock {$env:computername} -ErrorVariable localremotingerror -ErrorAction SilentlyContinue
 
 $options = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
 $resultssl = New-PSSession -UseSSL -ComputerName "localhost" -SessionOption $options -ErrorVariable localremotingsslerror -ErrorAction SilentlyContinue


 if (!$result -and $resultssl)
 {
    Write-Verbose "HTTP-based sessions not enabled, HTTPS based sessions enabled"
 }
 ElseIf (!$result -and !$resultssl)
 {
    Write-error "Could not establish session on either HTTP or HTTPS. Breaking"
 }


 #at this point, make sure there is a SSL-based listener
 $listeners = dir WSMan:\localhost\Listener

 if (!($listeners | where {$_.Keys -like "TRANSPORT=HTTPS"}))
 {
    #HTTPS-based endpoint does not exist.
    if (($CreateSelfSignedCert) -and ($OSVersion -notmatch "2012"))
    {
        $thumprint = New-LegacySelfSignedCert -SubjectName $env:COMPUTERNAME
    }
    if (($CreateSelfSignedCert) -and ($OSVersion -match "2012"))
    {
        $cert = New-SelfSignedCertificate -DnsName $env:COMPUTERNAME -CertStoreLocation "Cert:\LocalMachine\My"
        $thumprint = $cert.Thumbprint
    }
    
    
    
    # Create the hashtables of settings to be used.
    $valueset = @{}
    $valueset.add('Hostname',$env:COMPUTERNAME)
    $valueset.add('CertificateThumbprint',$thumprint)

    $selectorset = @{}
    $selectorset.add('Transport','HTTPS')
    $selectorset.add('Address','*')

    Write-Verbose "Enabling SSL-based remoting"
    New-WSManInstance -ResourceURI 'winrm/config/Listener' -SelectorSet $selectorset -ValueSet $valueset 
 }
 Else
 {
    Write-Verbose "SSL-based remoting already active"
 }


 #Check for basic authentication
 $basicauthsetting = Get-ChildItem WSMan:\localhost\Service\Auth | where {$_.Name -eq "Basic"}

 if (($basicauthsetting.Value) -eq $false)
 {
    Write-Verbose "Enabling basic auth"
    Set-Item -Path "WSMan:\localhost\Service\Auth\Basic" -Value $true
 }
 Else
 {
    Write-verbose "basic auth already enabled"
 }
 
#FIrewall
netsh advfirewall firewall add rule Profile=public name="Allow WinRM HTTPS" dir=in localport=5986 protocol=TCP action=allow



 Write-Verbose "PS Remoting successfully setup for Ansible"