Importing PowerShell sessions from computers has been a common practice for a while now. By avoiding to login to the exchange server, sessions can be imported easily with the appropriate access rights. After all, there are the same commands available as on the server.
The question is: what if the computer we need access to is outside the domain? There are a few obstacles to overcome here. In this article I would like to show you how this is done.
Index
Establish trust
Two computers within the same domain have a trusted connection because they belong to the same domain. They know who the other one is. It functions the same way between two computers on two different domains with an established trust relationship. If that is not the case, the computers will not trust each other. This means a trust relationship must be established first between them.
To simplify the explanation a little, I hereby define the computer on which the PowerShell script is to be run, as Computer A. Next, the computer which is to import the PowerShell session, as Computer B. To create a trust relationship, Computer B must be added to the list of trusted hosts of Computer A.
If you want to run a script without user interaction which requires the imported session you have to follow step one first. Set up a trust relationship before you run the script (and not as part of the script). Note that this requires user interaction from you which you cannot automate due to security reasons.
Read more about this topic in article >> User interactive PowerShell scripts.
Check TrustedHosts list
First, you need to know how to reach Computer B. If the computer is known by the DNS server, then you just need the name. If not, then you need the IP address. You can always add both to the list of trusted hosts, just to be on the safe side. To do so, you must open PowerShell as an administrator and type in the following command line:
1 |
Set-Item wsman:\localhost\Client\TrustedHosts -Value "<IP-Address>,<Servername>" |
In case you only have the IP address or only the name, enter it in the value parameter without a comma. Subsequently, PowerShell will ask for confirmation which you must answer with Y.
Afterwards use the command below to find out which items are on the TrustedHosts list.
1 |
Get-Item wsman:\localhost\Client\TrustedHosts |
Should you need to add more to the list, you can use the command below to do so.
1 |
Set-Item wsman:\localhost\Client\TrustedHosts -Value "<IPAddressOrServername>" –Concatenate |
Enable PowerShell remoting
As a next step, check whether PowerShell remoting is enabled. This applies to computers on the same domain as well as to non-domain ones. In our scenario, PS remoting must be enabled on Computer B so that it can import a PS session from a remote computer (Computer A).
To enable PS remoting, open PowerShell and type in the command below.
1 |
Enable-PSRemoting |
Pass credentials
If Computer A and Computer B share the same domain, the script can be executed from an account that has the permission to run PowerShell on the domain. As this is not the case in our scenario, a credential needs to be passed to the New-PSSession cmdlet. First, we have to create the credential before we can proceed.
Create credentials
Use the PowerShell console for your commands. With a simple
1 |
$credential = Get-Credential |
a user request is created, in which you can enter the relevant credentials. The newly created credential will then be saved in the variable.
If you run the cmdlet in a non-interactive script, the script will freeze at this point. That is why the credential should be generated automatically. However, the challenge is that the password is required to be a Secure-String. You can create a Secure-String from a normal string directly in the source code. Unfortunately, it means that you have to save the password in clear text directly in the script code. This is a huge security issue that should be avoided.
Generate credentials automatically
Instead, we can store the password relatively well-encrypted and still be able to decrypt it, if needed. The following command shows how to convert a string into a Secure-String. As a final step, we save it encrypted in a file.
1 2 |
$file = "C:\password.txt" "<Password>" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File $file |
Note: Although the password is saved encrypted (which means that it cannot be read just by opening the file), anyone with permissions to open this file will be able to read and use this password in his own PS script. To stay away from potential risks, never leave your file on unsecured computers.
Next, you need to generate credentials using the encrypted password. The prompt looks like that:
1 2 3 4 |
$username = "<Domain>\<Username>" $file = "C:\password.txt" $pw = Get-Content $file | ConvertTo-SecureString $credential = New-Object System.Management.Automation.PSCredential($username,$pw) |
Import a PS session
We have reached the last step to import PowerShell sessions from computers who are located on another domain. At last we have gathered everything we need for our PS session on Computer B. So the session can now be opened with the following prompt:
1 |
$session = New-PSSession -Computername "<Computer B>" - Credential $credential |
Simply import the entire session with:
1 |
Import-PSSession $session |
Should you want to spare resources, use the prompt Invoke-Command to start individual cmdlets in the session on Computer B. The following example shows how to stop a Windows-Service on Computer B:
1 |
Invoke-Command -ScriptBlock { Stop-Service -DisplayName $args[0]} -ArgumentList "<Service-DisplayName>" -Session $session |
Finally, you should delete the session once you have carried out all required actions:
1 |
Remove-PSSession $session |
Import PowerShell sessions summary and script
To sum it up, here are all the prompts you need to use chronologically:
Preparation:
1 2 |
#Computer A Set-Item wsman:\localhost\Client\TrustedHosts -Value "<IP-Address>,<Servername>" |
1 2 |
#Computer B Enable-PSRemoting |
If you want to run a non-interactive script:
1 2 3 |
#Computer A $file = "C:\password.txt" "<Password>" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File $file |
Open and use a remote session:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#Computer A #During interactive usage $credential = Get-Credential #Using non-interactive scripts $username = "<Domain>\<Username>" $file = "C:\password.txt" $pw = Get-Content $file | ConvertTo-SecureString $credential = New-Object System.Management.Automation.PSCredential($username,$pw) $session = New-PSSession -Computername "<Computer B>" - Credential $credential #Import complete session.. Import-PSSession $session #..or execute single commands within the session Invoke-Command -ScriptBlock { Stop-Service -DisplayName $args[0]} -ArgumentList "<Service-DisplayName>" -Session $session Remove-PSSession $session |
I hope you gained some valuable insights in how to import PowerShell sessions from outside your domain. Should you have any further questions, please contact us.
FirstAttribute AG – Identity Management & IAM Cloud Services
We would be happy to present our services and solutions to you. Get in touch and find out how we can help you.
3 Comments
Leave your reply.