• If scripts are not enabled, run PowerShell as Administrator and call:

    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm
  • Install PowerShell Community Extensions

Determine what version of PowerShell is installed


Install Modules

Persistent History

$MaximumHistoryCount = 31KB
$PoshHistoryPath = "$home\_posh_history.xml"

# Load history if history file exists
if (Test-path $PoshHistoryPath)
    { Import-CliXml $PoshHistoryPath | Add-History }

# Save history on exit, remove duplicates
Register-EngineEvent PowerShell.Exiting {
    Get-History -Count $MaximumHistoryCount | Group CommandLine |
    Foreach {$_.Group[0]} | Export-CliXml "$home\_posh_history.xml"
    } -SupportEvent

# hg function to search history
function hg($arg) {
    Get-History -c $MaximumHistoryCount | out-string -stream |
    select-string $arg


# PSReadline
Import-Module PSReadLine
Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete


Write a file in UTF-8 without the BOM


Out-File -Encoding "UTF8" force the BOM when using UTF-8. Use the following:

[System.IO.File]::WriteAllLines($File, $Contents)

Control Processes

Get-Process shows current processes. You can kill a process with Stop-Process and process ID:

Get-Process ProcessName | Stop-Process

For example:

Get-Process ClipboardHelpAndSpell | Stop-Process

GNU/Linux commands equivalents

PowerShell Community Extensions (PSCX)


  • Get-PathVariable
  • Set-PathVariable
  • Add-PathVariable



New-PSSession -ComputerName localhost

Get-PSSession -ComputerName localhost | Disconnect-PSSession

PowerShell Remoting vs ssh

  • In PowerShell Remoting, basically everything happens in the local machine; you send cmdlets to remote machines and get the results back.
  • With ssh, one logs into a remote machine, and then use a utility such as screen to make persistent sessions.
  • With PowerShell Remoting, one generates PSSessions from the local machine, and then Enter those PSSessions via Enter-Pssession.

Enable Remoting

On the remote computer:


Check the port on the remote machine


On the local computer:

cd WSMan:\localhost\Listener
WSMan:\localhost\Listener> dir
WSMan:\localhost\Listener> cd .\Listener_1084132640
WSMan:\localhost\Listener\Listener_1084132640> dir
Name Value
---- -----
Address *
Transport HTTP
Port 5985

Configure TrustedHosts

On the local computer:

Set-Item WSMan:\localhost\Client\TrustedHosts *
Set-Item WSMan:\localhost\Client\TrustedHosts $office
Restart-Service winrm

You can check it by:

Get-Item WSMan:\localhost\Client\TrustedHosts

Connect to the remote machine

On the local computer:

$targetServer = "xxx.xx.xxx.xx"
$remotePowerShellPort = 5985

$ConnectionURI = ("http://{0}:{1}" -f $targetServer, $remotePowerShellPort)


$remoteSession = New-PSSession -ConnectionURI $ConnectionURI

Invoke-Command -Session $remoteSession -ScriptBlock {Get-Process} -AsJob


Enter-PSSession -ConnectionURI $ConnectionURI



Enter-PSsession without session argument makes a temporary PSSession automatically, which is not persistent. You have to make a PSSession first via New-PSSession and then enter into that PSSession.


In default WinRM configuration, you can skip -ConnectionURI and http:// and use the ip address as the computer name.

With credentials

$Cred = Get-Credential "remotecomputername\username"
Enter-PSSession XXX.XX.XX.XX -Credential $cred

Interactive Remote Session

Open a persistent interactive session:

$s = New-PSSession -ConnectionURI $ConnectionURI
Enter-PSSession -Session $s

Disconnect from the session:

Disconnect-PSSession -Session $s -OutputBufferingMode Drop -IdleTimeoutSec 2147483647

Recover the session:

$session = Get-PSSession -ConnectionURI $ConnectionURI

You can re-enter the remoting session:

Enter-PSSession -Session $s


It seems this session is limited in a sense that console outputs will not be shown correctly; for example, invoking vim will make console to hang. I haven’t figured out how to fix this. It seems it is a inherent problem of remoting.

Remote Disconnected Sessions

about Remote Disconnected Sessions

  1. Creates a session to the ConnectionURI computer:

    > New-PSSession -ConnectionURI $ConnectionURI

    > New-PSSession -ConnectionURI $ConnectionURI -Name “IPython Notebook Server”

  2. To get the session, use the ConnectionURI parameter of Get-PSSession with a value of $ConnectionURI:

    > Get-PSSession -ConnectionURI $ConnectionURI
  3. To disconnect a PSSession use the Disconnect-PSSession cmdlet:

    > Get-PSSession -ConnectionURI $ConnectionURI | Disconnect-PSSession
  4. To connect a disconnected PSSession, use the Connect-PSSession cmdlet:

    > Connect-PSSession -ConnectionURI $ConnectionURI -Name Session2
  5. Run a command remotely in a disconnected session:

    > Invoke-Command -ConnectionURI $ConnectionURI -InDisconnectedSession -ScriptBlock {ipython notebook --profile=nbserver}
  6. Run a command remotely as a job in a disconnected session:

    > $s =  Invoke-Command -ConnectionURI $ConnectionURI -InDisconnectedSession -ScriptBlock {Start-Job -ScriptBlock {ipython notebook --profile=nbserver}}
    • In this case, you need to do Receive-PSSession to be able to access the session:

      > Receive-PSSession $s

Start A Remote Job that Returns the Results to the Local Computer (Asjob)


Runs the command as a background job on a remote computer. Use this parameter to run commands that take an extensive time to complete.

When you use AsJob, the command returns an object that represents the job, and then displays the command prompt. You can continue to work in the session while the job completes. To manage the job, use the Job cmdlets. To get the job results, use the Receive-Job cmdlet.

For example:

$ Invoke-Command -ConnectionURI $ConnectionURI -ScriptBlock {python C:\Users\joon\Dropbox\playground.py} -AsJob
$ Invoke-Command -ConnectionURI $ConnectionURI -ScriptBlock {ipython notebook --profile=nbserver} -AsJob


Problem with this is that since the results are returned to the local computer, once the local session is ended, the results are lost. I think the job gets lost as well.

Start A Remote Job that Keeps the Results on the Remote Computer


I think this can be very useful.

  1. Generate a new PSSession, or connect to an existing one. Let $s denote the session variable.

  2. Invoke a command as a Start-Job in the session:

    Invoke-Command -Session $s -ScriptBlock {Start-Job -ScriptBlock {python C:\Users\joon\Dropbox\playground.py}}
  3. You can Disconnect-Pssession -Session $s freely, without killing the job.

  4. To get list of jobs in the session $s:

    Invoke-Command -Session $s -ScriptBlock {Get-Job}
  5. To get the output from the job:

    Invoke-Command -Session $s -ScriptBlock {Receive-Job JobId -keep}

Example: one session, multiple remote jobs

# Open a new PSSession
> $s = New-PSSession -ConnectionURI $ConnectionURI -Name Persistent

# Invoke command on the remote server
> {Start-Job -Name NBServer -ScriptBlock {ipython notebook --profile=nbserver}} | % { Invoke-Command -Session $s -ScriptBlock $_; };

# Disconnect $s with maximum IdleTimeoutSec
> Disconnect-PSSession -Session $s -OutputBufferingMode Drop -IdleTimeoutSec 2147483647

# Conncet to $s
> Connect-PSSession $s

# Run additional jobs
> {Start-Job -Name Playground -ScriptBlock {python C:\Users\joon\Dropbox\playground.py}} | % { Invoke-Command -Session $s -ScriptBlock $_; };

# Get list of jobs in $s
> {Get-Job} | % { Invoke-Command -Session $s -ScriptBlock $_; };

# Get the output from the job with name Playground
> {Receive-Job -Name Playground -Keep} | % { Invoke-Command -Session $s -ScriptBlock $_; };