Intrinsic functions
Not functions per-se. Native PowerShell commands are called cmdlets—they are .NET classes, have a common parameter/argument system and play well with the pipeline. You can now do the same with advanced functions directly in the PowerShell language, though.
There's plenty of built-in cmdlets for file I/O, process control, WMI access and shell-specific stuff such as managing variables, aliases, modules, &c.
Furthermore you have the complete .NET framework at your disposal where you can find the various math functions for example and everything else not easily possible with PowerShell alone.
Basic test/branch/loop functions and flow control
The usual C-like statements: if
, switch
, for
, while
, do
, foreach
. Note that curly braces delimit blocks and all those statements expect blocks (not blocks or a single statement as in many other languages). Details can be found with Get-Help about_If
(and about_Switch
, about_for
, about_while
, about_do
, about_foreach
). Especially switch
is insanely powerful, allowing for regular expression matching and other niceties which often can serve as a simple makeshift parser.
Intrinsic types of variables (boolean, integer, floating-point, string)
Assign $true
or $false
to a variable and it is a boolean, assign an integer to a variable and it becomes Int32
, Int64
, Decimal
or Double
, depending on how large it is. You won't surprisingly land at −231 because of overflow. Floating point numbers and strings can be similarly constructed with the usual notation. You can always declare an explicit type if you don't like the default choice:
PS> [long]$a = 5 # 5 would usually result in [int], not [long]
Intrinsic data structures (scalar, list, associative array, object)
You can easily have scalars:
PS> $a = "foo"
or lists (well, they are arrays underneath):
PS> $b = 5, 2, "bar"
or hash tables (associative arrays):
PS> $c = @{ 'a' = 5; 7 = 'foo' }
Both arrays and hash tables are by default based on Object
. To get stronger type constraints here you need to jump through a few hoops.
Operators and operator precedence
Operators can be found in Get-Help about_Operators
.
Arithmetic (see about_arithmetic_operators
)
+ - * / % ++ --
Assignment (see about_assignment operators
)
= += -= *= /= %=
Logical (see about_logical_operators
)
-and -or -xor -not !
Pretty straightforward; !
is just another name for -not
which may be of help to those rooted in C-like languages.
Bitwise
-band -bor -bxor -bnot
Comparison operators
Since PowerShell is a shell they can't simply use >
and <
which are reserved for redirection, hence the slightly more cumbersome variants:
-lt -le -eq -ge -gt -ne
Others
There are also two flavors of string matching operators: -match
for regular expression matching and -like
for wildcard matching; their negated variants: -notmatch
, -notlike
; and their explicitly case-sensitive and case-insensitive cousins (default is case-insensitive): -cmatch
, -imatch
, -cnotmatch
, -inotmatch
, -clike
, -ilike
, -cnotlike
, -inotlike
. See about_comparison_operators
)
Then there are a few more special operators, such as redirection operators (see about_redirection
):
> >> 2> 2>> 2>&1
Split and Join (new in PowerShell v2):
-split -join
Those can split a string at a regular expression or join an array with a specified delimiter.
The replace operator -replace
which also allows for regular expressions.
The format operator -f
:
PS> "{0:N3} {1} {2:yyyy-MM-dd}" -f 123.456789,"foo",(Get-Date)
123,457 foo 2010-02-25
Range operator ..
:
PS> 1..10 -join ", "
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
As well as a bunch of others, such as the call operator &
, dot sourcing with .
, subexpressions with $( )
, array subexpressions with @( )
and the array construction operator ,
. This is getting out of hand here, though, so look these up yourself.
As for precedence, I doubt that's something you really need to know. If in doubt, use parentheses. The arithmetic operators use the usual rule (mul/div before add/sub). I haven't had much surprises with precedence myself so I didn't bother looking it up so far.
Functions specific to a task automation language
Process control (exec, fork, wait, kill)
It's a shell, so exec
is kinda implied. You can directly run other programs without problems. fork
is not a Windows thing, so no luck there. For wait
there is Wait-Process
which I believe does the same (if I'm reading the manpage right).
System monitoring (ps, uptime, lsof, fuser, netstat, df)
ps
is an alias to Get-Process
.
The system uptime can be queried via WMI and packaged in a handy function if needed:
function Get-SystemUptime
{
$os = Get-WmiObject Win32_OperatingSystem
(Get-Date) - [Management.ManagementDateTimeConverter]::ToDateTime($os.LastBootUpTime)
}
which returns a TimeSpan
object.
lsof
, fuser
might be grabbed from the process objects somehow; never did that, though. netstat
is still available as a native program you can simply run.
df
can be kinda emulated with
Get-PSDrive -PSProvider FileSystem
If you need it for more than just to look at it, WMI is probably the more sane way to go.
File and directory handling (find, locate, which, cd, mkdir, touch, rm, rmdir)
find
and locate
can usually be achieved via Get-ChildItem
and subsequent filtering of the results with Where-Object
.
which
maps to Get-Command
which, as of PowerShell v2 displays commands in the order in which they are considered for execution:
PS Home:\> gcm where
CommandType Name Definition
----------- ---- ----------
Alias where Where-Object
Application where.exe C:\Windows\system32\where.exe
cd
is an alias for Set-Location
. Possible locations not only include the file system but also the registry, variables, aliases, certificate store and others.
mkdir
is a function which ultimately maps to New-Item
with appropriate arguments.
touch
can be achieved with Set-ItemProperty
:
Set-ItemProperty foo.txt LastWriteTime (Get-Date)
You can put that in a function named touch
if you like.
rm
and rmdir
are aliases for Remove-Item
.
I/O (pipes, cat, tee, xargs, read, write, overwrite, append, seek)
- Pipelines use objects instead of bytes, which should be the most significant different in comparison to other shells. Apart from that not too many surprises. Many cmdlets accept pipeline input.
cat
is an alias for Get-Content
.
tee
is an alias for Tee-Object
. It not only allows writing to a file but you can also capture it in a variable for example:
Get-Process
| Tee-Object -Variable proc
| Select-Object ProcessName,CPU
xargs
can be replaced by ForEach-Object
as far as I can see.
- Byte-oriented file I/O is probably better done with normal .NET objects and method calls. It's easy enough to get a complete file as a string with
Get-Content
but beyond that it's a little cumbersome.
Text-processing functions (awk, sed, grep, split, join, cut, fmt, strings)
Most text-processing functions are not that desperately needed like on UNIX systems as you won't need them to dissect command output, for example—at least not when you're dealing with cmdlets which return objects that allow for far easier access of their properties.
Beyond that there are various tools for text-processing. Depending on what you need to do switch -regex
and the -match
, -replace
and -split
operators can make up for most uses of sed
, awk
, cut
, split
, join
I've seen.
No strings
or fmt
.
Is PowerShell strongly-typed (char, string, int, long, float, double) or weakly-typed (variant)?
PowerShell uses the .NET type system. Variables are implicitly strongly-typed, but not declared. They can be given an explicit type, though.
Are common data structures available (scalar, list, associative array) and are they first-class elements?
You can therefore use any .NET data structure from the System.Collections
namespace. Generic collections are a little painful to set up but it can be done. As mentioned before, lists of elements and hash tables are language elements as well.
Is there a library or module system?
PowerShell v2 does have modules which are collections of cmdlets of related functionality. See Get-Help about_Modules
for more details.
If so, what is in the standard library?
More than would be sensible to describe here. You can call Get-Command
to see what's available. Get-Help
as usual helps in finding out what any given thing does.
Are there third-party libraries I can use if I don’t find what I need?
You can dynamically load any .Net assembly using
[System.Reflection.Assembly]::LoadFrom(...)
or (in PowerShell v2) with Add-Type
:
Add-Type -AssemblyName ...
Is this a procedural, functional, or object-oriented language—or to what extent each?
Wikipedia says Multi-paradigm: imperative, pipeline, object-oriented, functional, reflective. The object pipeline aspect is a nice way of achieving elegant solutions for some problem domains.
It's object-oriented in the way that you primarily use objects to achieve your goal, you rarely model something with objects in PowerShell. You can't create own classes (not counting Add-Type
which allows you to write, compile and import C# or VB code on the fly) so in terms of abstraction for own work within the PowerShell language you'll probably be more on a procedural level.
What are the coding conventions? (Perl Best Practices)
The language is still very young so there is not yet such a thing (at least I'm not aware of it). However, when trying to code-golf PowerShell code it became apparent that it's hard to create utterly unreadable messes. The usual rules for curly-brace languages work quite well and for longer pipelines breaking them into several lines often helps readability.
Are there formatting expectations—line-oriented or free-form?
Not sure how to answer that: Mostly line-oriented, but piped commands may be better readable with every command in a single line.
If you call a built-in, you can use ` (grave accent) as line continuation mark.
Is whitespace or case significant?
No. Except for line breaks which usually terminate a command, unless preceded by the escape character or when they occur within blocks or other surrounding structures.
Is there a character set limitation?
No.
Is the language “8-bit clean”?
Yes. We're no longer in Ye Olde Ages of the 70es. You can also easily name variables, functions as you wish with no constraints. I named a function ♦
(U+0004), for example, which allows me to hit Ctrl+D, Enter to close a session.
Does it support UTF-8, Unicode, etc.?
As PowerShell uses .Net, you have full Unicode support. Input and output streams can be set to various encodings.