PowerShell is an object-oriented product—all the language features and constructs are based on objects: cmdlets emit objects, variables are objects, and language constructs allow you to manipulate objects. You can use the properties of an object and can call methods an object contains. While some PowerShell users may not make much direct use of this object orientation, PowerShell is able to make use of .NET and WMI objects, both at the command line and in scripts. Like most of PowerShell's features, we could devote an entire book to the subject of objects in PowerShell.
PowerShell is built on the .NET Framework and enables you to access and use most of the classes within the framework. A restriction of PowerShell version 1 is that the asynchronous classes and methods are not supported.
Using .NET objects is pretty easy since much of it happens by default. You can either let PowerShell determine the .NET classes by default—for example, typing LS
or DIR
in a filesystem drive produces a set of file and directory objects. You can see this by piping the output of a command to the Get-Member
cmdlet, as shown here:
PSH [D:\foo]:ls
Directory: Microsoft.PowerShell.Core\FileSystem::D:\foo Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 14/10/2007 12:04 bar -a--- 09/09/2007 12:30 3 foo.txt -a--- 14/10/2007 19:42 13 helloworld.ps1 PSH [D:\foo]:dir | Get-Member
TypeName: System.IO.DirectoryInfo Name MemberType Definition ---- ---------- ---------- Create Method System.Void Create( ), System.Void Create(DirectorySecurity CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(Type requested ... output snipped for brevity TypeName: System.IO.FileInfo Name MemberType Definition ---- ---------- ---------- AppendText Method System.IO.StreamWriter AppendText( ) CopyTo Method System.IO.FileInfo CopyTo(String dest Create Method System.IO.FileStream Create( ) CreateObjRef Method System.Runtime.Remoting.ObjRef Create CreateText Method System.IO.StreamWriter CreateText( ) Decrypt Method System.Void Decrypt( ) Delete Method System.Void Delete( ) Encrypt Method System.Void Encrypt( ) Equals Method System.Boolean Equals(Object obj) ... output snipped for brevity
In the above example, the LS
command emitted System.IO.DirectoryInfo
and System.IO.FileInfo
objects. To many Windows admins not familiar with the .NET, this looks quite complex, but it does become second nature with a bit of practice. For more information on System.IO.DirectoryInfo
objects, see http://msdn2.microsoft.com/en-us/library/system.io.directoryinfo.aspx and for more information on System.IO.FileInfo
objects, see http://msdn2.microsoft.com/en-us/library/system.io.fileinfo.aspx.
You can also directly create .NET objects. For example, you could use the New-Object
cmdlet as shown here to access .NET's random number class System.Random
:
PSH [D:\foo]:$rand = New-Object System.Random
PSH [D:\foo]:$rand.next( )
92298896 PSH [D:\foo]:$rand.next( )
1722419986 PSH [D:\foo]:$rand2 = New-Object System.Random
PSH [D:\foo]:$rand2.NextDouble( )
0.370553521611986 PSH [D:\foo]:$rand2.nextdouble( )
0.561135980561905
If you want to create random numbers that are between two other numbers (e.g., a random number between 1 and 10, or between 4 and 16), you can specify a bottom and top range in a call to .NEXT( )
, as shown here:
PSH [D:\foo]: $rand = New-Object System.Random PSH [D:\foo]: $rand.next(1,10) 7 PSH [D:\foo]: $rand.next(4,16) 14
WMI objects are created using the Get-WMIObject
cmdlet. Like .NET objects, WMI objects have properties and methods you can call. Unlike normal .NET objects, you can access WMI objects remotely. There are a very large number of WMI classes, as shown at http://msdn2.microsoft.com/en-us/library/aa394554.aspx.
PowerShell can also access COM objects, which is useful for accessing legacy applications that expose them. An example of this is using WMI to examine the Vista Firewall:
With PowerShell, you can use the firewall COM object to obtain details of the Windows Firewall. Here's a simple example that shows how to get the Firewall COM object and the related Firewall profile, which you can then manipulate:
PSH [D:\foo]: $fw = new-object -com HNetCfg.FwMgr PSH [D:\foo]: $profile = $fw.LocalPolicy.CurrentProfile
Once you get this object created, you can examine it and determine your firewall setup as follows:
PSH [D:\foo]:# determine global open ports (NB there aren't any!)
PSH [D:\foo]:$profile.GloballyOpenPorts | ft name, port
PSH [D:\foo]:# determine authorized applications
PSH [D:\foo]:$profile.AuthorizedApplications | ? {$_.Enabled} | ft name
Name ---- localsrv SMTPServer Virtual PC 2007 WS_FTP 95 iTunes Microsoft Office OneNote Microsoft Office Groove PSH [D:\foo]: # determine enabled services PSH [D:\foo]: $profile.Services | ? {$_.Enabled} | ft name Name ---- File and Printer Sharing Network Discovery PSH [D:\foo]: #determine enabled services (ports)
PSH [D:\foo]:$profile.Services | ? {$_.Enabled} | select -expand GloballyOpenPorts
Name : File and Printer Sharing (NB-Session-In) IpVersion : 2 Protocol : 6 Port : 139 Scope : 1 RemoteAddresses : LocalSubnet Enabled : True BuiltIn : True Name : File and Printer Sharing (SMB-In) IpVersion : 2 Protocol : 6 Port : 445 Scope : 1 RemoteAddresses : LocalSubnet Enabled : True BuiltIn : True {remainder of output snipped}