Powershellorg A Unix Persons Guide To Powershell Master
Powershellorg A Unix Persons Guide To Powershell Master
people
PowerShell.org
2015 PowerShell.org
Contents
About
Principal author: Matt Penny
This e-book is intended as a Quick Start guide to PowerShell for people who already know Bash or
one of the other Unix shells.
The book has 3 elements:
Microsoft Virtual Academys Getting Started with PowerShell and Advanced Tools & Scripting with PowerShell Jump Start courses - these are recordings of day long webcasts, and are
both free.
unix-like aliases
PowerShell is a friendly environment for Unix people to work in. Many of the concepts are similar,
and the PowerShell team have built in a number of Powershell aliases that look like unix commands.
So, you can, for example type:
1 ls
Length
-----25773
3390
Name
---all_the_details .md
commands - summary .md
6
These can be quite useful when youre switching between shells, although I found that it can be
irritating when the muscle-memory kicks in and you nd yourself typing ls -ltr in PowerShell and
get an error. The ls is just an alias for the PowerShell get-childitem and the Powershell command
doesnt understand -ltr[1].
the pipeline
The PowerShell pipeline is much the same as the Bash shell pipeline. The output of one command
is piped to another one with the | symbol.
The big dierence between piping in the two shells is that in the unix shells you are piping text,
whereas in PowerShell you are piping objects.
This sounds like its going to be a big deal, but its not really.
In practice, if you wanted to get a list of process names, in bash you might do this:
1 ps -ef | cut -c 49 -70
In Bash you working with characters, or tab-delimited elds. In PowerShell you work with eld names,
which are known as properties.
but get-history has 4 other properties which you might or might not be interested in:
1
2
3
4
5
6
7
:
:
:
:
:
1
dir -recurse c:\ temp
Completed
06/05/2015 13:46:56
06/05/2015 13:47:07
7
The disparity between what is shown and what is available is even greater for more complex entities
like process. By default get-process shows 8 columns, but there are actually over 50 properties (as
well as 20 or so methods) available.
The full range of what you can return from a PowerShell command is given by the get-member
command[2].
To run get-member, you pipe the output of the command youre interested in to it, for example:
1 get - process | get - member
get-member
get-help
get-command
get-help
get-help
8
23
methods that let you start and stop the process . You can also use the
parameters of Get - Process to get file
version information for the program that runs in the process and to get the
modules that the process loaded .
24
25
26
27 RELATED LINKS
28
Online Version : http :// go. microsoft .com/ fwlink /? LinkID =113324
29
Debug - Process
30
Get - Process
31
Start - Process
32
Stop - Process
33
Wait - Process
34
35 REMARKS
36
To see the examples , type: "get -help Get - Process -examples ".
37
For more information , type: "get -help Get - Process -detailed ".
38
For technical information , type: "get -help Get - Process -full ".
39
For online help , type: "get -help Get - Process -online "
There are a couple of wrinkles which actually make the PowerShell help even more help-ful.
you get basic help by typing get-help, more help by typing get-help -full andprobably the
best bit as far as Im concernedyou can cut to the chase by typing get-help -examples
there are lots of about_ pages. These cover concepts, new features (in for example
and subjects which dont just relate to one particular command.
You can see a full list of the about topics by typing get-help about
about_Windows_Powershell_5.0)
get-help works like man -k or apropos. If youre not sure of the command you want to see help
on, just type help process and youll see a list of all the help topics that talk about processes.
If there was only one it would just show you that topic
Comment-based help. When you write your own commands you can (and should!) use the
comment-based help functionality. You follow a loose template for writing a comment header
block, and then this becomes part of the get-help subsystem. Its good.
get-command
If you dont want to go through the help system, and youre not sure what command you need, you
can use get-command.
I use this most often with wild-cards either to explore whats available or to check on spelling.
For example, I tend to need to look up the spelling of ConvertTo-Csv on a fairly regular basis.
PowerShell commands have a very good, very intuitive naming convention of a verb followed by a
noun (for example, get-process, invoke-webrequest), but Im never quite sure where to and from
go for the conversion commands.
To quickly look it up I can type:
get-command *csv*
which returns:
1
2
3
4
5
6
7
8
9
10
11
12
Name
---epcsv -> Export -Csv
ipcsv -> Import -Csv
ConvertFrom -Csv
ConvertTo -Csv
Export -Csv
Import -Csv
ucsvc .exe
vmicsvc .exe
ModuleName
----------
Functions
Typically PowerShell coding is done in the form of functions[4]. What you do to code and write a
function is this:
Create a function in a plain text .ps1 le[5]
1 gvim say - HelloWorld .ps1
File is missing
then source the function when they need it
1 $ . .\say - HelloWorld .ps1
then run it
1 $ say - helloworld
2 Hello , World
Often people autoload their functions in their $profile or other startup script, as follows:
1
2
3
4
5
6
## Footnotes
[1] If you wanted the equivalent of ls -ltr you would use gci | sort lastwritetime. gci is an alias
for get-childitem, and I think, sort is an alias for sort-object.
[2] Another way of returning all of the properties of an object is to use select *so in this case you
could type get-process | select *
10
[3] There is actually a built-in alias man which tranlates to get-help, so you can just type man if youre
pining for Unix.
[4] See the following for more detail on writing functions rather than scripts: http://blogs.technet.
com/b/heyscriptingguy/archive/2011/06/26/don-t-write-scripts-write-powershell-functions.aspx
[5] Im using gvim here, but notepad would work just as well. PowerShell has a free scripting
environment called PowerShell ISE, but you dont have to use it if you dont want to.
commands summary
alias (set aliases)
1 set - alias
More
More
apropos
1 get -help
More
basename
1 dir | select name
More
cal
No equivalent, but see the script at http://www.vistax64.com/powershell/17834-unix-cal-command.
html\char003C\relax{}/a>
11
12
cd
1 cd
More
clear
1 clear -host
More
date
1 get -date
More
date -s
1 set -date
More
df -k
1 Get - WMIObject Win32_LogicalDisk | ft -a
More
dirname
1 dir | select directory
More
du
No equivalent, but see the link
13
echo
1 write - output
More
echo -n
1 write -host -nonewline
More
| egrep -i sql
1
More
egrep -i
1 select - string
More
egrep
1 select - string
-casesensitive
More
egrep -v
1 select - string -notmatch
More
14
env
1 Get - ChildItem Env: | fl
or
get-variable
More
errpt
1 get - eventlog
More
export PS1=$
1 function prompt {"$ " }
More
nd
1 dir
* whatever * -recurse
More
More
head
1 gc file.txt | select - object -first 10
More
15
history
1 get - history
More
history | egrep -i ls
1 history | select commandline | where commandline -like '*ls*' | fl
More
hostname
1 hostname
More
if-then-else
1 if
More
if [ -f $FileName ]
1 if (test -path $FileName )
More
kill
1 stop - process
More
less
1 more
More
16
locate
1 no equivalent but see link
More
ls
1 get - childitem OR gci OR dir OR ls
More
ls -a
1 ls -force
More
ls -ltr
1 dir c:\ | sort - object -property lastwritetime
More
lsusb
1 gwmi Win32_USBControllerDevice
More
mailx
1 send - mailmessage
More
man
1 get -help
More
17
more
1 more
More
mv
1 rename -item
More
pg
1 more
More
ps -ef
1 get - process
More
More
pwd
1 get - location
More
read
1 read -host
More
18
rm
1 remove -item
More
script
1 start - transcript
More
sleep
1 start - sleep
More
sort
1 sort - object
More
sort -uniq
1 get - unique
More
tail
1 gc file.txt | select - object -last 10
More
tail -f
1 gc -tail 10 -wait file.txt
More
19
time
1 measure - command
More
More
More
wc -l
1 gc ./ file.txt | measure - object | select count
More
whoami
1 [ Security . Principal . WindowsIdentity ]:: GetCurrent () | select name
More
whence or type
1 No direct equivalent , but see link
More
unalias
1 remove -item -path alias : aliasname
More
20
uname -m
1 Get - WmiObject -Class Win32_ComputerSystem | select manufacturer , model
More
uptime
1 get - wmiobject -class win32_operatingsystem | select LastBootUpTime `
More
(line continuation)
1 ` (a backtick )
More
commands detail - a
alias (list all the aliases)
The Powershell equivalent of typing alias at the bash prompt is:
1 get - alias
If you try doing this in Powershell, it doesnt work so well. If you do this:
1 set - alias cdtemp "cd c:\ temp"
2 cdtemp
21
22
You can then create an alias for the function:
1 set - alias cdt cdtemp
apropos
is one of my favourite bash commands, not so much for what it doesbut because I like the
word apropos.
apropos
Im not sure it exists on all avours of *nix, but in bash apropos returns a list of all the man pages
which have something to do with what youre searching for. If apropos isnt implemented on your
system you can use man -k instead.
Anyway on bash, if you type:
1 apropos process
AF_LOCAL [unix]
(7) - Sockets for local interprocess communication
AF_UNIX [unix]
(7) - Sockets for local interprocess communication
Apache2 :: Process
(3 pm) - Perl API for Apache process record
BSD :: Resource
(3 pm) - BSD process resource limit and priority functions
CPU_CLR [ sched_setaffinity ] (2) - set and get a process 's CPU affinity mask
CPU_ISSET [ sched_setaffinity ] (2) - set and get a process 's CPU affinity mask
CPU_SET [ sched_setaffinity ] (2) - set and get a process 's CPU affinity mask
CPU_ZERO [ sched_setaffinity ] (2) - set and get a process 's CPU affinity mask
GConf2
(rpm) - A process - transparent configuration system
Category
-------Function
Function
Cmdlet
Cmdlet
Module
------
Synopsis
-------Get processes for a particul ...
Show processes for a particu ...
Microso ... Debugs one or more processes ...
Microso ... Gets the processes that are ...
This is quite a nice feature of PowerShell compared to Bash. If get-help in Powershell shell scores
a direct hit (i.e. you type something like get-help debug-process) it will show you the help for that
particular function. If you type something more vague, it will show you a list of all the help pages
you might be interested in.
By contrast if you typed man process at the Bash prompt, youd just get
1 No manual entry for process
commands detail - b
basename
A rough PowerShell equivalent for the unix basename is:
1 dir <whatever > | select name
Notes
[1] I found [System.IO.Path]::GetFileName after reading Power Tips of the Day - Useful Path Manipulations Shortcuts, which has some other useful commands
23
commands detail - c
cal
Theres no one-liner equivalent for the Linux cal, but theres a useful script, with much of the cal
functionality here :
http://www.vistax64.com/powershell/17834-unix-cal-command.html\char003C\relax{}/a>
cd
The PowerShell equivalent of cd is:
1 Set - Location
cd ~
cd ~
clear
The unix clear command clears your screen. The Powershell equivalent to the unix clear is
1 clear -host
25
cp
The Posh version of cp is
1 copy -item
cp -R
To recursively copy:
1 copy -recurse
commands detail - d
date
The Powershell equivalent of the Unix date is
1 get -date
I was anticipating doing a fairly tedious exercise of going through all the Unix date formats and then
working out the Powershell equivalent, but discovered the Powershell Team has eectively done all
this for me. There is a Powershell option -UFormat which stands for unix format.
So the Powershell:
1 date -Uformat '%D'
2 09/08/14
This is handybut I have found the odd dierence. I tried this for a demo:
Unix:
1 date +' Today is %A the %d of %B, the %V week of the year %Y. My timezone is %Z, and
here it is %R'
2 Today is Monday the 08 of September , the 37 week of the year 2014. My timezone is
BST , and here it is 17:24
Powershell:
1 get -date -Uformat 'Today is %A the %d of %B, the %V week of the year %Y. My
timezone is %Z, and here it is %R'
2 Today is Monday the 08 of September , the 36 week of the year 2014. My timezone is
+01 , and here it is 17:25
26
27
I presume the discrepancy in the week of the year is to do with when the week turns - as you can see
I ran the command on a Monday. Some systems have the turn of the week being Monday, others
have it on Sunday.
I dont know why \%Z outputs dierent things.and I cant help feeling Im being churlish pointing
this out. The -UFormat option is a really nice thing to have.
df -k
A quick and dirty Powershell equivalent to df -k is
1 Get - WMIObject Win32_LogicalDisk -filter " DriveType =3" | ft
.and get
1
2
3
4
5
SystemName
---------my_server
my_server
my_server
DeviceID
-------C:
D:
E:
VolumeName
---------OS
App
size(GB)
-------30.0
250.0
40.0
freespace (GB)
------------7.8
9.3
5.0
dirname
A good PowerShell equivalent to the unix dirname is
1 gi c:\ double_winners \ chelsea .doc | select directory
However, this isnt a direct equivalent. Here, Im telling Powershell to look at an actual le and then
return that les directory. The le has to exist. The unix dirname doesnt care whether the le
you specify exists or not. If you type in dirname /tmp/double_winners/chelsea.doc on any Unix server
it will return /tmp/double_winners, I think. dirname is essentially a string-manipulation command.
A more precise Powershell equivalent to the unix dirname is this
28
.but its not as easy to type, and 9 times out of 10 I do want to get the folder for an existing le
rather than an imaginary one.
du
While I think there are implementations of du in PowerShell, personally my recommendation would
be to download Mark Russinovichs du tool, which is here:
Windows Sysinternals - Disk Usage
This is part of the Microsofts sysinternals suite.
commands detail - e
echo
is an alias in PowerShell. As you would expect its an alias for the closest equivalent to the
Linux echo:
echo
write-output
As well as write-output there are a couple of options for use in Powershell scripts and functions:
write-debug
write-verbose
echo -n
In bash, echo -n echoes back the string without printing a newline, so if you do this:
1 $ echo -n Blue is the colour
you get:
1 Blue is the colour$
.with your cursor ending up on the same line as the output, just after the dollar prompt
Powershell has an exact equivalent of echo -n. If you type:
1 PS C:\ Users \matt > write -host -nonewline "Blue is the colour "
30
egrep
The best PowerShell equivalent to egrep or grep is select-string:
1 select - string stamford blue_flag .txt
A nice feature of select-string which isnt available in grep is the -context option. The -context
switch allows you to see a specied number of lines either side of the matching one. I think this is
similar to SEARCH /WINDOW option in DCL.
egrep -i
Powershell is case-insensitive by default, so:
1 select - string stamford blue_flag .txt
would return:
blue_flag.txt:3:From Stamford Bridge to Wembley
egrep -v
The Powershell equivalent to the -v option would be -notmatch
1 select - string -notmatch stamford blue_flag .txt
egrep this|that
To search for more than one string within a le in bash, you use the syntax:
1 egrep 'blue|stamford ' blue_flag .txt
returns:
1 blue_flag .txt :2:We 'll keep the blue flag flying high
2 blue_flag .txt :3: From Stamford Bridge to Wembley
3 blue_flag .txt :4:We 'll keep the blue flag flying high
31
| egrep -i sql
This is an interesting one, in that it points up a conceptual dierence between PowerShell and Bash.
In bash, if you want to pipe into a grep, you would do this:
1 ps -ef | egrep sql
This would show you all the processes which include the string sql somewhere in the line returned
by ps. The egrep is searching across the whole line. If the username is mr_sql then a line would
be returned, and if the process is sqlplus than a line would also be returned.
To do something similar in PowerShell you would do something more specic
1 get - process | where processname -like '*sql*'
So the string sql has to match the contents of the property processname. As it happens, get-process
by default only returns one text eld, so in this case its relatively academic, but hopefully it illustrates
the point.
env
The Linux env shows all the environment variables.
In PowerShell there are two set of environment variables:
- windows-level variables and
- Powershell-level variable
Windows-level variables are given by:
1 Get - ChildItem Env: | fl
errpt
I think errpt is possibly just an AIX thing (the linux equivalent is, I think, looking at /var/log/message).
It shows system error and log messages.
The PowerShell equivalent would be to look at the Windows eventlog, as follows
1 get - eventlog -computername bigserver -logname application -newest 15
32
export PS1=$
In bash the following changes the prompt when you are at the command line
1 export PS1 ="$ "
commands detail - f
nd
The bash find command has loads of functionality - I could possibly devote many pages to Powershell
equivalents of the various options, but at its simplest the bash find does this:
1
2
3
4
5
6
7
8
9
The simplest Powershell equivalent of the bash find is simply to stick a -recurse on the end of a dir
command
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PS x:\> dir
*BB.txt -recurse
LastWriteTime
------------28/02/2012
17:15
28/02/2012
17:17
28/02/2012
17:17
28/02/2012
17:15
Length
-----608
44
14567
1961
Name
---Script_WO8559_Master_ScriptBB .txt
WO8559_finalBB .txt
WO8559_part1BB .txt
WO8559_part2BB .txt
Length
-----2972
3662
3839
Name
---Script_WO7171BB .txt
Script_WO8541BB .txt
Script_WO8645_BB .txt
LastWriteTime
------------15/06/2011
08:56
14/02/2012
16:39
27/02/2012
15:22
If you want Powersehll to give you output that looks more like the Unix nd then you can pipe into
| select fullname
1 PS x:\> dir
33
34
2
3
4
5
6
7
8
9
10
11
FullName
-------x:\ Archive \ WO8559B \ Script_WO8559_Master_ScriptBB .txt
x:\ Archive \ WO8559B \ WO8559_finalBB .txt
x:\ Archive \ WO8559B \ WO8559_part1BB .txt
x:\ Archive \ WO8559B \ WO8559_part2BB .txt
x:\ Archive \ Script_WO7171BB .txt
x:\ Archive \ Script_WO8541BB .txt
x:\ Archive \ Script_WO8645_BB .txt
for
for loop - start, stop, step
The equivalent of this bash:
1
2
3
4
5
6
7
8
9
10
world
world
world
world
world
1
2
3
4
5
is
1
2
3
4
5
6
7
8
9
10
world
world
world
world
world
1
2
3
4
5
35
Posh:
1 select - string -notmatch millwall london .txt | select line | foreach {write - output
$_}
or:
1 foreach ($team in (select - string -notmatch millwall london .txt | select line))
{ $team}
Posh:
1 foreach ( $LocalFile in $(gci)) {write - output $LocalFile .Name}
10 commands detail - g
Not got any commands beginning with g yet.
36
11 commands detail - h
head
The PowerShell equivalent of the *nix head is:
1 gc file.txt | select - object -first 10
history
The Powershell equivalent of history is:
1 get - history
Name
---CommandLine
EndExecutionTime
ExecutionStatus
ExecutionStatus
11 Id
12 StartExecutionTime
MemberType
---------Property
Property
Property
{get ;}
Property
Property
Definition
---------string CommandLine {get ;}
datetime EndExecutionTime {get ;}
System . Management . Automation . Runspaces . PipelineState
long Id {get ;}
datetime StartExecutionTime {get ;}
history | egrep -i ls
There is no direct equivalent of the shell functionality you get with set -o vi sadly. You can upand down- arrow by default, but if you want to search through your history then you need to do
37