Read Windows Server 2008 R2 Unleashed Online
Authors: Noel Morimoto
New-Object : Constructor not found. Cannot find an appropriate constructor for type
System.Math.
At line:1 char:11
+ New-Object <<<< System.Math
+ CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.
Commands.NewObjectCommand
PS C:\>
The reason this occurs is because static members are shared across all instances of a class
and don’t require a typed object to be created before being used. Instead, static members
are accessed simply by referring to the class name as if it were the name of the object
followed by the static operator (::), as follows:
PS > [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
In the previous example, the DirectoryServices.ActiveDirectory.Forest class is used to
retrieve information about the current forest. To complete this task, the class name is
enclosed within the two square brackets ([...]). Then, the GetCurrentForest method is
invoked by using the static operator (::).
NOTE
To retrieve a list of static members for a class, use the Get-Member cmdlet: Get-
Member -inputObject ([System.String]) -Static.
Understanding the PowerShell Basics
713
Type Accelerators
A type accelerator is simply an alias for specifying a .NET type. Without a type accelerator,
21
defining a variable type requires entering a fully qualified class name, as shown here:
PS C:\> $User = [System.DirectoryServices.DirectoryEntry]”LDAP:
//CN=Fujio Saitoh,OU=Accounts,OU=Managed Objects,DC=companyabc,DC=com”
PS C:\> $User
distinguishedname:{CN=Fujio Saitoh,OU=Accounts,OU=Managed
Objects,DC=companyabc,DC=com}
path : LDAP:
//CN=Fujio Saitoh,OU=Accounts,OU=Managed Objects,DC=companyabc,DC=com
PS C:\>
Instead of typing the entire class name, you just use the [ADSI] type accelerator to define
the variable type, as in the following example:
PS C:\> $User = [ADSI]”LDAP://CN=Fujio Saitoh,OU=Accounts, OU=Managed
Objects,DC=companyabc,DC=com”
PS C:\> $User
ptg
distinguishedname:{CN=Fujio Saitoh,OU=Accounts,OU=Managed
Objects,DC=companyabc,DC=com}
path : LDAP:
//CN=Fujio Saitoh,OU=Accounts,OU=Managed Objects,DC=companyabc,DC=com
PS C:\>
Type accelerators have been included in PowerShell mainly to cut down on the amount of
typing to define an object type. However, for some reason, type accelerators aren’t covered
in the PowerShell documentation, even though the [WMI], [ADSI], and other common
type accelerators are referenced on many web blogs.
Regardless of the lack of documentation, type accelerators are a fairly useful feature of
PowerShell. Table 21.2 lists some of the more commonly used type accelerators.
TABLE 21.2
Important Type Accelerators in PowerShell
Name
Type
Int
System.Int32
Long
System.Int64
String
System.String
Char
System.Char
714
CHAPTER 21
Automating Tasks Using PowerShell Scripting
TABLE 21.2
T
Important Type Accelerator
tant T
s in Pow
s in P
erShell
ow
Name
Type
Name
Type
Bool
System.Boolean
Byte
System.Byte
Double
System.Double
Decimal
System.Decimal
Float
System.Float
Single
System.Single
Regex
System.Text.RegularExpressions.Regex
Array
System.Array
Xml
System.Xml.XmlDocument
Scriptblock
System.Management.Automation.ScriptBlock
Switch
System.Management.Automation.SwitchParameter
Hashtable
System.Collections.Hashtable
ptg
Type
System.Type
Ref
System.Management.Automation.PSReference
Psobject
System.Management.Automation.PSObject
pscustomobject
System.Management.Automation.PSCustomObject
Psmoduleinfo
System.Management.Automation.PSModuleInfo
Powershell
System.Management.Automation.PowerShell
runspacefactory
System.Management.Automation.Runspaces.RunspaceFactory
Runspace
System.Management.Automation.Runspaces.Runspace
Ipaddress
System.Net.IPAddress
Wmi
System.Management.ManagementObject
Wmisearcher
System.Management.ManagementObjectSearcher
Wmiclass
System.Management.ManagementClass
Adsi
System.DirectoryServices.DirectoryEntry
Adsisearcher
System.DirectoryServices.DirectorySearcher
Understanding the PowerShell Basics
715
The Pipeline
21
In the past, data was transferred from one command to the next by using the pipeline,
which makes it possible to string a series of commands together to gather information
from a system. However, as mentioned previously, most shells have a major disadvantage:
The information gathered from commands is text based. Raw text needs to be parsed
(transformed) into a format the next command can understand before being piped.
The point is that although most UNIX and Linux shell commands are powerful, using
them can be complicated and frustrating. Because these shells are text based, often
commands lack functionality or require using additional commands or tools to perform
tasks. To address the differences in text output from shell commands, many utilities and
scripting languages have been developed to parse text.
The result of all this parsing is a tree of commands and tools that make working with
shells unwieldy and time consuming, which is one reason for the proliferation of manage-
ment interfaces that rely on GUIs. This trend can be seen among tools Windows adminis-
trators use, too; as Microsoft has focused on enhancing the management GUI at the
expense of the CLI.
Windows administrators now have access to the same automation capabilities as their
UNIX and Linux counterparts. However, PowerShell and its use of objects fill the automa-
ptg
tion need Windows administrators have had since the days of batch scripting and WSH in
a more usable and less parsing-intense manner. To see how the PowerShell pipeline works,
take a look at the following PowerShell example:
PS C:\> get-process powershell | format-table id -autosize
Id
--
3628
PS C:\>
NOTE
All pipelines end with the Out-Default cmdlet. This cmdlet selects a set of properties
and their values and then displays those values in a list or table.
Modules and Snap-Ins
One of the main design goals behind PowerShell was to make extending the default func-
tionality in PowerShell and sharing those extensions easy enough that anyone could do it.
In PowerShell 1.0, part of this design goal was realized through the use of snap-ins.
716
CHAPTER 21
Automating Tasks Using PowerShell Scripting
PowerShell snap-ins (PSSnapins) are dynamic-link library (DLL) files that can be used to
provide access to additional cmdlets or providers. By default, a number of PSSnapins are
loaded into every PowerShell session. These default sets of PSSnapins contain the built-in
cmdlets and providers that are used by PowerShell. You can display a list of these cmdlets
by entering the command Get-PSSnapin at the PowerShell command prompt, as follows:
PS C:\> get-pssnapin
Name : Microsoft.PowerShell.Core
PSVersion : 2.0
Description : This Windows PowerShell snap-in contains Windows PowerShell manage-
ment cmdlets used to manage components
of Windows PowerShell.
Name : Microsoft.PowerShell.Host
PSVersion : 2.0
Description : This Windows PowerShell snap-in contains cmdlets used by the Windows
PowerShell host.
ptg
...
PS C:\>
In theory, PowerShell snap-ins were a great way to share and reuse a set of cmdlets and
providers. However, snap-ins by definition must be written and then compiled, which
often placed snap-in creation out of reach for many IT professionals. Additionally, snap-
ins can conflict, which meant that attempting to run a set of snap-ins within the same
PowerShell session might not always be feasible.
That is why in PowerShell 2.0, the product team decided to introduce a new feature, called
modules, which are designed to make extending PowerShell and sharing those extensions
significantly easier. In its simplest form, a module is just a collection of items that can be
used in a PowerShell session. These items can be cmdlets, providers, functions, aliases,
utilities, and so on. The intent with modules, however, was to allow “anyone” (developers
and administrators) to take and bundle together a collection of items. These items can
then be executed in a self-contained context, which will not affect the state outside of the
module, thus increasing portability when being shared across disparate environments.
Remoting
With PowerShell 1.0, one of its major disadvantages was the lack of an interface to execute
commands on a remote machine. Granted, you could use Windows Management
Instrumentation (WMI) to accomplish this and some cmdlets like Get-Process and Get-
Service, which enable you to connect to remote machines. But, the concept of a native-
based “remoting” interface was sorely missing when PowerShell was first released. In fact,
Understanding the PowerShell Basics
717
the lack of remote command execution was a glaring lack of functionality that needed to
be addressed. Naturally, the PowerShell product team took this functionality limitation to
21
heart and addressed it by introducing a new feature in PowerShell 2.0, called “remoting.”
Remoting, as its name suggests, is a new feature that is designed to facilitate command (or
script) execution on remote machines. This could mean execution of a command or
commands on one remote machine or thousands of remote machines (provided you have
the infrastructure to support this). Additionally, commands can be issued synchronously
or asynchronously, one at time or through a persistent connection called a runspace, and
even scheduled or throttled.
To use remoting, you must have the appropriate permissions to connect to a remote
machine, execute PowerShell, and execute the desired command(s). In addition, the
remote machine must have PowerShell 2.0 and Windows Remote Management (WinRM)
installed, and PowerShell must be configured for remoting.
Additionally, when using remoting, the remote PowerShell session that is used to execute
commands determines execution environment. As such, the commands you attempt to
execute are subject to a remote machine’s execution policies, profiles, and preferences.
WARNING
ptg
Commands that are executed against a remote machine do not have access to infor-
mation defined within your local profile. As such, commands that use a function or
alias defined in your local profile will fail unless they are defined on the remote
machine as well.
How Remoting Works
In its most basic form, PowerShell remoting works using the following conversation flow
between “a client” (most likely the machine with your PowerShell session) and “a server”
(remote host) that you want to execute command(s) against:
1. A command is executed on the client.
2. That command is transmitted to the server.
3. The server executes the command and then returns the output to the client.
4. The client displays or uses the returned output.
At a deeper level, PowerShell remoting is very dependent on WinRM for facilitating the
command and output exchange between a “client” and “server.” WinRM, which is a
component of Windows Hardware Management, is a web-based service that enables
administrators to enumerate information on and manipulate a remote machine. To
handle remote sessions, WinRM was built around a SOAP-based standards protocol called
WS-Management. This protocol is firewall-friendly, and was primarily developed for the
exchange of management information between systems that might be based on a variety
of operating systems on various hardware platforms.
When PowerShell uses WinRM to ship commands and output between a client and server,
that exchange is done using a series of XML messages. The first XML message that is
718
CHAPTER 21
Automating Tasks Using PowerShell Scripting
exchanged is a request to the server, which contains the desired command to be executed.
This message is submitted to the server using the SOAP protocol. The server, in return,
executes the command using a new instance of PowerShell called a runspace. Once execu-
tion of the command is complete, the output from the command is returned to the
requesting client as the second XML message. This second message, like the first, is also
communicated using the SOAP protocol.
This translation into an XML message is performed because you cannot ship “live” .NET
objects (how PowerShell relates to programs or system components) across the network.