MegaBites-AI/Windows-powershell
0308
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 