####################################################### ## REMOTELY ENABLE PSREMOTING ## Script written by The Curious Geek ## http://thecuriousgeek.org ####################################################### $strComputer = read-host "Enter the PC Name to enable remoting" ## Create the C$ on the remote PC $classString = "\\" + $strComputer + "\Root\Cimv2:win32_share" $newshareobj = [WmiClass] $classString $shareExitCode = $newshareobj.Create("C:\","C$",0,25,"Admin Share") ## Creating my share path $sharePath = "\\" + $strComputer + "\C$" ## Start logic to set bat files, tasks, and execute them If ($shareExitCode.returnValue -eq 0 -or $shareExitCode.returnValue -eq 22) { # Return code 0 is a success, 22 means it probably already existed Set-Content $sharePath\Scripts\enablePSRemoting.bat "powershell.exe ""Start-process powershell.exe -verb RunAs """"enable-psremoting -force -skipnetworkprofilecheck""""""" # Will launch powershell which is in a normal session, that opens another elevated shell to enable PSRemoting. all those quotes are necessary to get proper quoting in the final .bat file $existCheck = test-path $sharePath\Scripts\enablePSRemoting.bat # making sure it set the file If (!$existCheck) { Write-host "Batch file failed to create" } Else { ## Now lets create the task on the remote PC and run it remove-variable $matches # clear matches (a global, system variable) so we can accurately get the ID of the task that gets created $createTask = "cmd.exe /c at \\$strComputer %time% C:\Scripts\enablePSRemoting.bat" # make sure you update this path if you changed where you saved the script. Using At will ensure it runs as system so it will be in a session invisble to the user. $taskResult = invoke-expression $createTask # executes the string variable that we just created as if it were typed at the prompt $taskIDCheck = $taskResult -match "\d+" # get the task ID so we can start it and delete it. \d+ is a regular expresion to look for a number of one or more digits. the text results of creating a task only has one number in it. $taskID = $matches[0] # the result will be the first match in the array since there will only be one match $runTask = "cmd.exe /c schtasks /RUN /S $strComputer /TN At$taskID" invoke-expression $runTask # executing the string command that actually runs the task *now* on the PC instead of waiting for it to run at a set time in the future Start-Sleep -s 5 # sleep for 5 seconds before deleting task to give it time to execute. Deleting it so it can't be used unsuspectingly later! $delTask = "cmd.exe /c schtasks /DELETE /S $strComputer /TN At$taskID /F" invoke-expression $delTask ## WinRM should now be enabled ## Now lets modify the firewall rule so WinRM isn't open to the public! Set-Content $sharePath\Scripts\PSRemoteFirewall.bat "netsh advfirewall firewall set rule name=""Windows Remote Management (HTTP-In)"" profile=domain new enable=yes" Add-Content $sharePath\Scripts\PSRemoteFirewall.bat "netsh advfirewall firewall set rule name=""Windows Remote Management (HTTP-In)"" profile=private,public new enable=yes profile=private" $existCheck = test-path "\\$strComputer\C$\Scripts\PSRemoteFirewall.bat" If (!$existCheck) { LogIt "Batch file failed to create" } Else { ## Items here are similar as above so I wont comment them remove-variable $matches # clear matches so we can accurately get the ID of the task that gets created $createTask = "cmd.exe /c at \\$strComputer %time% C:\Scripts\PSRemoteFirewall.bat" $taskResult = invoke-expression $createTask LogIt "Executed command to create task" $taskIDCheck = $taskResult -match "\d+" $taskID = $matches[0] $runTask = "cmd.exe /c schtasks /RUN /S $strComputer /TN At$taskID" invoke-expression $runTask Start-Sleep -s 5 $delTask = "cmd.exe /c schtasks /DELETE /S $strComputer /TN At$taskID /F" invoke-expression $delTask } ## Now that tasks are complete, lets delete the .bat files so no one can stumble upon them and use them remove-item $sharePath\Scripts\enablePSRemoting.bat remove-item $sharePath\Scripts\PSRemoteFirewall.bat ## Lets set a certain regkey that can block certain remoting tasks, even WMI. This key sometimes gets set, sometimes doesn't and I don't know what does it. So lets just make sure it's "open" $rpcPath = "SYSTEM\CurrentControlSet\Control\Terminal Server" #this key is in the RDP path but it affects other types of remoting as well $rpcKey = [Microsoft.Win32.Registrykey]::OpenRemoteBaseKey("LocalMachine", $strComputer) $setKey = $rpcKey.OpenSubKey($rpcPath, $true) $setKey.SetValue("AllowRemoteRPC", "0", "DWord") } } Else { Write-host "Unable to create C$" }