PowerShell¶
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¶
$psversiontable.psversion
Install Modules¶
PowerShell Resource Gallery¶
https://msconfiggallery.cloudapp.net/
Install-Module -Name PSReadline
Install-Module -Name PSReadline -Scope CurrentUser
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¶
# PSReadline
Import-Module PSReadLine
Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
Text¶
Write a file in UTF-8 without the BOM¶
http://stackoverflow.com/questions/5596982/using-powershell-to-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¶
which
Equivalent of *Nix ‘which’ command in Powershell?:
function which($name) { Get-Command $name | Select-Object -ExpandProperty Definition }
PowerShell Community Extensions (PSCX)¶
Symbolic Link¶
New-Symlink
New-Junction
New-Hardlink
Path¶
Get-PathVariable
Set-PathVariable
Add-PathVariable
Remoting¶
http://superuser.com/questions/643120/windows-powershell-screen-equivalent/643606
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 asscreen
to make persistent sessions. - With PowerShell Remoting, one generates
PSSessions
from the local machine, and then Enter thosePSSessions
viaEnter-Pssession
.
Check the port on the remote machine¶
http://stackoverflow.com/questions/5458565/powershell-remote-enabling
On the local computer:
cd WSMan:\localhost\Listener
WSMan:\localhost\Listener> dir
[cut]
WSMan:\localhost\Listener> cd .\Listener_1084132640
WSMan:\localhost\Listener\Listener_1084132640> dir
WSManConfig:
icrosoft.WSMan.Management\WSMan::localhost\Listener\Listener_1084132640
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)
Invoke-Command:
$remoteSession = New-PSSession -ConnectionURI $ConnectionURI
Invoke-Command -Session $remoteSession -ScriptBlock {Get-Process} -AsJob
Enter-PSSession:
Enter-PSSession -ConnectionURI $ConnectionURI
Exit-PSSession
Note
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
.
Note
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:
Exit-PSSession
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
Note
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
Creates a session to the
ConnectionURI
computer:> New-PSSession -ConnectionURI $ConnectionURI
> New-PSSession -ConnectionURI $ConnectionURI -Name “IPython Notebook Server”
To get the session, use the
ConnectionURI
parameter ofGet-PSSession
with a value of$ConnectionURI
:> Get-PSSession -ConnectionURI $ConnectionURI
To disconnect a PSSession use the
Disconnect-PSSession
cmdlet:> Get-PSSession -ConnectionURI $ConnectionURI | Disconnect-PSSession
To connect a disconnected PSSession, use the
Connect-PSSession
cmdlet:> Connect-PSSession -ConnectionURI $ConnectionURI -Name Session2
Run a command remotely in a disconnected session:
> Invoke-Command -ConnectionURI $ConnectionURI -InDisconnectedSession -ScriptBlock {ipython notebook --profile=nbserver}
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)¶
http://technet.microsoft.com/en-us/library/hh849719.aspx
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
Note
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¶
http://technet.microsoft.com/en-us/library/hh847805.aspx
I think this can be very useful.
Generate a new
PSSession
, or connect to an existing one. Let$s
denote the session variable.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}}
You can
Disconnect-Pssession -Session $s
freely, without killing the job.To get list of jobs in the session
$s
:Invoke-Command -Session $s -ScriptBlock {Get-Job}
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 $_; };