Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
Install-PowerShellRemoting.ps1233 linesDownload Raw Back to powershell-native
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4#####################################################################################################5#6# Registers the WinRM endpoint for this instance of PowerShell.7#8# If the parameters '-PowerShellHome' were specified, it means that the script will be registering9# an instance of PowerShell from another instance of PowerShell.10#11# If no parameter is specified, it means that this instance of PowerShell is registering itself.12#13# Assumptions:14#     1. The CoreCLR and the PowerShell assemblies are side-by-side in $PSHOME15#     2. Plugins are registered by version number. Only one plugin can be automatically registered16#        per PowerShell version. However, multiple endpoints may be manually registered for a given17#        plugin.18#19#####################################################################################################20[CmdletBinding(DefaultParameterSetName = "NotByPath")]21param22(23    [parameter(Mandatory = $true, ParameterSetName = "ByPath")]24    [switch]$Force,25    [string]26    $PowerShellHome27)28 29Set-StrictMode -Version 3.030 31if (! ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))32{33    Write-Error "WinRM registration requires Administrator rights. To run this cmdlet, start PowerShell with the `"Run as administrator`" option."34    return35}36function Register-WinRmPlugin37{38    param39    (40        #41        # Expected Example:42        # %windir%\\system32\\PowerShell\\6.0.0\\pwrshplugin.dll43        #44        [string]45        [parameter(Mandatory=$true)]46        [ValidateNotNullOrEmpty()]47        $pluginAbsolutePath,48 49        #50        # Expected Example: powershell.6.0.0-beta.351        #52        [string]53        [parameter(Mandatory=$true)]54        [ValidateNotNullOrEmpty()]55        $pluginEndpointName56    )57 58    $regKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin\$pluginEndpointName"59 60    $pluginArchitecture = "64"61    if ($env:PROCESSOR_ARCHITECTURE -match "x86" -or $env:PROCESSOR_ARCHITECTURE -eq "ARM")62    {63        $pluginArchitecture = "32"64    }65    $regKeyValueFormatString = @"66<PlugInConfiguration xmlns="http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration" Name="{0}" Filename="{1}"67    SDKVersion="2" XmlRenderingType="text" Enabled="True" OutputBufferingMode="Block" ProcessIdleTimeoutSec="0" Architecture="{2}"68    UseSharedProcess="false" RunAsUser="" RunAsPassword="" AutoRestart="false">69    <InitializationParameters>70        <Param Name="PSVersion" Value="7.0"/>71    </InitializationParameters>72    <Resources>73        <Resource ResourceUri="http://schemas.microsoft.com/powershell/{0}" SupportsOptions="true" ExactMatch="true">74            <Security Uri="http://schemas.microsoft.com/powershell/{0}" ExactMatch="true"75            Sddl="O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)"/>76            <Capability Type="Shell"/>77        </Resource>78    </Resources>79    <Quotas IdleTimeoutms="7200000" MaxConcurrentUsers="5" MaxProcessesPerShell="15" MaxMemoryPerShellMB="1024" MaxShellsPerUser="25"80    MaxConcurrentCommandsPerShell="1000" MaxShells="25" MaxIdleTimeoutms="43200000"/>81</PlugInConfiguration>82"@83    $valueString = $regKeyValueFormatString -f $pluginEndpointName, $pluginAbsolutePath, $pluginArchitecture84 85    New-Item $regKey -Force > $null86    New-ItemProperty -Path $regKey -Name ConfigXML -Value $valueString > $null87}88 89function New-PluginConfigFile90{91    [CmdletBinding(SupportsShouldProcess, ConfirmImpact="Medium")]92    param93    (94        [string]95        [parameter(Mandatory=$true)]96        [ValidateNotNullOrEmpty()]97        $pluginFile,98 99        [string]100        [parameter(Mandatory=$true)]101        [ValidateNotNullOrEmpty()]102        $targetPsHomeDir103    )104 105    # This always overwrites the file with a new version of it if the106    # script is invoked multiple times.107    Set-Content -Path $pluginFile -Value "PSHOMEDIR=$targetPsHomeDir" -ErrorAction Stop108    Add-Content -Path $pluginFile -Value "CORECLRDIR=$targetPsHomeDir" -ErrorAction Stop109 110    Write-Verbose "Created Plugin Config File: $pluginFile" -Verbose111}112 113function Install-PluginEndpoint {114    [CmdletBinding(SupportsShouldProcess, ConfirmImpact="Medium")]115    param (116        [Parameter()] [bool] $Force,117        [switch]118        $VersionIndependent119    )120 121    ######################122    #                    #123    # Install the plugin #124    #                    #125    ######################126 127    if (-not [String]::IsNullOrEmpty($PowerShellHome))128    {129        $targetPsHome = $PowerShellHome130        $targetPsVersion = & "$targetPsHome\pwsh" -NoProfile -Command '$PSVersionTable.PSVersion.ToString()'131    }132    else133    {134        ## Get the PSHome and PSVersion using the current powershell instance135        $targetPsHome = $PSHOME136        $targetPsVersion = $PSVersionTable.PSVersion.ToString()137    }138    Write-Verbose "PowerShellHome: $targetPsHome" -Verbose139 140    # For default, not tied to the specific version endpoint, we apply141    # only first number in the PSVersion string to the endpoint name.142    # Example name: 'PowerShell.6'.143    if ($VersionIndependent) {144        $dotPos = $targetPsVersion.IndexOf(".")145        if ($dotPos -ne -1) {146            $targetPsVersion = $targetPsVersion.Substring(0, $dotPos)147        }148    }149 150    Write-Verbose "Using PowerShell Version: $targetPsVersion" -Verbose151 152    $pluginEndpointName = "PowerShell.$targetPsVersion"153 154    $endPoint = Get-PSSessionConfiguration $pluginEndpointName -Force:$Force -ErrorAction silentlycontinue 2>&1155 156    # If endpoint exists and -Force parameter was not used, the endpoint would not be overwritten.157    if ($endpoint -and !$Force)158    {159        Write-Error -Category ResourceExists -ErrorId "PSSessionConfigurationExists" -Message "Endpoint $pluginEndpointName already exists."160        return161    }162 163    if (!$PSCmdlet.ShouldProcess($pluginEndpointName)) {164        return165    }166 167    if ($PSVersionTable.PSVersion -lt "6.0")168    {169        # This script is primarily used from Windows PowerShell for Win10 IoT and NanoServer to setup PSCore6 remoting endpoint170        # so it's ok to hardcode to 'C:\Windows' for those systems171        $pluginBasePath = Join-Path "C:\Windows\System32\PowerShell" $targetPsVersion172    }173    else174    {175        $pluginBasePath = Join-Path ([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::Windows) + "\System32\PowerShell") $targetPsVersion176    }177 178    $resolvedPluginAbsolutePath = ""179    if (! (Test-Path $pluginBasePath))180    {181        Write-Verbose "Creating $pluginBasePath"182        $resolvedPluginAbsolutePath = New-Item -Type Directory -Path $pluginBasePath183    }184    else185    {186        $resolvedPluginAbsolutePath = Resolve-Path $pluginBasePath187    }188 189    $pluginPath = Join-Path $resolvedPluginAbsolutePath "pwrshplugin.dll"190 191    # This is forced to ensure the file is placed correctly192    Copy-Item $targetPsHome\pwrshplugin.dll $resolvedPluginAbsolutePath -Force -Verbose -ErrorAction Stop193 194    $pluginFile = Join-Path $resolvedPluginAbsolutePath "RemotePowerShellConfig.txt"195    New-PluginConfigFile $pluginFile (Resolve-Path $targetPsHome)196 197    # Register the plugin198    Register-WinRmPlugin $pluginPath $pluginEndpointName199 200    ####################################################################201    #                                                                  #202    # Validations to confirm that everything was registered correctly. #203    #                                                                  #204    ####################################################################205 206    if (! (Test-Path $pluginFile))207    {208        throw "WinRM Plugin configuration file not created. Expected = $pluginFile"209    }210 211    if (! (Test-Path $resolvedPluginAbsolutePath\pwrshplugin.dll))212    {213        throw "WinRM Plugin DLL missing. Expected = $resolvedPluginAbsolutePath\pwrshplugin.dll"214    }215 216    try217    {218        Write-Host "`nGet-PSSessionConfiguration $pluginEndpointName" -ForegroundColor "green"219        Get-PSSessionConfiguration $pluginEndpointName -ErrorAction Stop220    }221    catch [Microsoft.PowerShell.Commands.WriteErrorException]222    {223        throw "No remoting session configuration matches the name $pluginEndpointName."224    }225}226 227Install-PluginEndpoint -Force $Force228Install-PluginEndpoint -Force $Force -VersionIndependent229 230Write-Host "Restarting WinRM to ensure that the plugin configuration change takes effect.`nThis is required for WinRM running on Windows SKUs prior to Windows 10." -ForegroundColor Magenta231Restart-Service winrm232 233