Introduction
For years, UNIX/Linux administrators have looked down on the Windows environment, one of the main reasons being that Windows did not have a nice CLI. UNIX has always had sh, bash, ksh which are great shells. Microsoft has now introduced Windows PowerShell (codename MONAD), a very powerful .NET based shell. A shell is a great tool for system administrators to automate tasks. PowerShell has all the same features as the current UNIX shells, like:
- Composition - Which is the combining of many little commands in order to create a complex function
- Pipes - Being able to pipe information from one command to the next
There are also a few features that set it apart from the other shell environments available on the nix* systems:
- Object Oriented - PowerShell is fully object oriented. This is one of my favourites, and why I think it is so much more powerful than bash. E.g., in bash, you have the ability to pipe a list of processes to another application. With this list of text, I can then search through it and find some process IDs which match a certain string. However in PowerShell, I get back a list of process objects, objects which have properties and methods.
- Access to the full .NET 2.0 assemblies - Need I say more?
- Extensibility - Create you own cmdlet assemblies, so people can script your application. Exchange 2007 is one of the first Windows applications to support PowerShell. Through PowerShell cmdlets, you can run scripts that will manage and automate the administration of exchange. For example, (PS> get-mailbox *noob* | set-mailbox -SendStorageQuota 1GB) would set the quoter for all names that had the string noob in their name.
- Hosting - Ability to host PowerShell in your .NET application in less than 10 lines of code. Because PowerShell is object oriented, you are able to pass objects from the hosting program into the script, in one line of code.
- Ability to use Windows COM objects.
- Strong XML support.
So let's get into it then...
- Start by getting the .NET 2.0 runtime from here: .NET Runtime download
- Then get PowerShell from here: Download PowerShell
- Next we need an IDE (this tool is pure gold for learning PowerShell and writing scripts): http://www.karlprosser.com/coder/?page_id=14
Before we can use the IDE, we need to enable all scripts to be executed. So from PowerShell (Start->Windows PowerShell->Windows PowerShell), we enable scripting.
PS > Get-Help Set-ExecutionPolicy - detailed
This will give us some information regarding Set-ExecutionPolicy Command.
PS > Set-ExecutionPolicy Unrestricted
Lets you run scripts from external sources.
P.S. It is made up of many cmdlets which are DLLs that get interpreted by PS. In the future, we can see how to create our own cmdlets so people can control our applications. For now, let's throw around some built in cmdlets:
Some samples
PS > get-service | get-member
Here the get-service cmdlet is piping a list of service objects to another cmdlet. Get-member is then listing all the available members in the "System.ServiceProcess.ServiceController
" class.
PS > get-service schedule | format-list -property *
Here, the get-service is getting the service object 'schedule' and piping it to another cmdlet which formats the output of the properties. There are other formats available, try...
PS > get-service | Format-List
PS > get-service | Format-Custom
PS > get-service | Format-Table
PS > get-service | Format-Wide
PS > get-service | format-table name, Servicetype, Canshutdown
Here we are piping information from ipconfig and filtering with the findstr command.
PS > ipconfig | findstr "Address"
Please note: ipconfig is a command that returns text so it is not returning objects with properties and functions.
Get-Help
There is a large amount of documentation with PS. Get-Help is much like the man command for nix.
Other options:
PS > Get-help get-command -detailed
PS > Get-help get-command -full
PS > Get-help get-command -examples
PS > Get-help get-command -parameter *
Common commands
PS > Get-Command - Gets basic information about cmdlets and about other elements
of Windows PowerShell commands.
PS > Get-Process - Gets the processes that are running on the local computer.
PS > Get-Service - Gets the services on the local computer
PS > Get-Eventlog - Gets information about local event logs or the entries stored in
those event logs.
PS > Start-transcript, stop-transcript - Lets you record sessions/interaction with PS
Alias (get-alias)
Alias's are literally command alias's. E.g.: 'ps' is an alias for get-process.
PS > get-alias ps
PS > get-alias | where-object {$_.definition -eq "set-location"}
PS > set-alias gh get-help
PS > set-alias np c:\windows\notepad.exe
PS > remove-item alias:ls
Variables, loops, and string manipulation
Being a scripting language, PS has support for variables, loops, and string manipulation.
Put the results into a variable:
$result = ipconfig
Using a for
loop to print out with line numbers..
for ($i=0 ; $i -lt $result.length; $i++ )
{
"{0} {1}" -f $i, $result[$i]
}
Using foreach
...
$i = 1;
foreach($singleLine in $result)
{
$i++
"{0} {1}" -f $i, $singleLine
}
Using built-in string functions...
PS > "How dooz is this".split()
Functions
Functions can be created as with any scripting language. Arguments can be passed and values returned.
$result = ipconfig
function AddLineNumbers
{
$i = 1;
foreach($singleLine in $args[0])
{
$i++
"{0} {1}" -f $i, $singleLine
}
}
AddLineNumbers $result
WMI (Windows Management Instrumentation) scripting
WMI is an essential technology for Windows administration. WMI gives you access to a huge amount of information for Windows systems. The Get-WmiObject
cmdlet provides access to WMI objects.
For example, here we are using Get-WmiObject
to get the OS and BIOS information.
Get-WmiObject win32_bios -computername 127.0.0.1
Get-WmiObject -Class Win32_OperatingSystem -ComputerName 127.0.0.1
.NET scripting
A common thing that you would do in scripting is send emails. First, we would need to create a mail message .NET object using New-Object
.
PS> $mailMsg = New-Object -TypeName System.Net.Mail.MailMessage(
" sender@net.com.au"," recipient@net.com.au");
Then we can set some options and the email message.
PS> $mailMsg.IsBodyHtml = $true;
PS> $mailMsg.Body = "<html>This is a sample mail message sent from PowerShell</html>";
PS> $mailMsg.Subject = "This is a sample mail message sent from PowerShell";
Once we have created the mail message, we then need to create the client object and send the email.
PS> $client = New-Object -TypeName System.Net.Mail.SmtpClient("mail.optusnet.com.au");
PS> $client.Send($mailMsg);
Shell profile
All aliases, functions, and variables are only added to the current session. In order to keep changes, you need to add them to your profile. Here is a list of profile locations:
%windir%\system32\WindowsPowerShell\v1.0\profile.ps1
This profile applies to all users and all shells.
%windir%\system32\WindowsPowerShell\v1.0\ Microsoft.PowerShell_profile.ps1
This profile applies to all users, but only to the Microsoft.PowerShell shell.
%UserProfile%\My Documents\WindowsPowerShell\profile.ps1
This profile applies only to the to the current user, but affects all shells.
%UserProfile%\\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
This profile applies only to the current user and the Microsoft.PowerShell shell.
You can also create, share, and distribute profiles.
Navigation
PS allows for navigation of the file system, Registry, and certificates on the computer using a common method. To view the available navigation areas, use:
get-psdrive
File system
As per normal.
Registry
cd HKLM:
ls
cd system\currentcontrolset\control
Further reading