Bookmark and Share

(Editor’s note: Portions of today's Hey, Scripting Guy! Blog post are excerpted from the Microsoft Press book, Windows PowerShell 2.0 Best Practices by Ed Wilson which is now available for pre-order.)

Hey, Scripting Guy! Question

Hey Scripting Guy! I am curious about the new cmdlets that are available in Windows PowerShell 2.0. Do you have some sort of a list?

-- RC

Hey, Scripting Guy! AnswerHello RC,

Microsoft Scripting Guy Ed Wilson here. Things are rather mellow around here this morning, I am listening to Gran Ventura from Madama Butterfly, and sipping a cup of Earl Gray tea and reviewing the e-mail sent to the scripter@microsoft.com inbox.

New cmdlets

The number of cmdlets in Windows PowerShell 2.0 has nearly doubled over the number that shipped with the original product. These are core cmdlets and do not take into account the number of cmdlets that are included with Windows 7.0. Many of these cmdlets are for use with remoting, and the underlying WSMan technology. On a Windows 7 computer with Microsoft Remote Server Administration Tools (RSAT) installed, there are 456 cmdlets. On a Windows 7 computer with all modules loaded, but without RSAT installed, there are 251 cmdlets. On a Windows 7 computer without the modules loaded there are 236 cmdlets. On a computer with Windows PowerShell 1.0 installed and with no snap-ins installed, there are 129 cmdlets. If you would like to see the cmdlets that are installed on your computer, you can use the Get-Command cmdlet as seen here:

Get-Command –commandtype cmdlet

If you want to see which modules are available on your computer that is running Windows PowerShell 2.0, you can use the Get-Module cmdlet as shown here:

Get-Module -listavailable

 

WMI Cmdlets

Some of the new cmdlets allow for easier use of Windows Management Instrumentation (WMI) to manage and configure your computer systems. These cmdlets are listed here:

Invoke-WmiMethod: Calls WMI methods. Depending on the method you are trying to perform, you will either need to specify the path to the object, or you can just call the method directly. In the first example, we delete a share named fso. To do this, we need to specify the path to the share. The name of the method we are using is the delete method. In the second example, we do not need to connect to a specific process because we are creating a process. The name of the method is create, and the argument we pass to the create method is the name of the process to create:

Invoke-WmiMethod -path "win32_share.name='fso'" -Name delete

Invoke-WmiMethod -Class win32_process -Name create -ArgumentList notepad.exe


Register-WmiEvent:
Registers for an event with the WMI eventing subsystem. To use this cmdlet, you write an event query using the WMI Query language (WQL) syntax. (For more information about event driven queries, refer to the Microsoft Press book, Microsoft Windows Scripting with WMI: Self-Paced Learning Guide.) In this example, we create an event that will tell us when a new process starts. The notification will contain the message, “A new process has started.” To receive this message we will need to use the Get-PSEvent cmdlet. This process will be examined next week when the Scripting Guys take on WMI eventing using Windows PowerShell 2.0.

Register-WMIEvent -query "Select * From __InstanceCreationEvent within 3 Where TargetInstance ` ISA 'Win32_Process'" -messageData "A new process has started." -sourceIdentifier "New Process"


Remove-WmiObject:
Deletes WMI classes and instances. By using the Remove-WmiObject cmdlet, we have another way to delete instances of classes. As an example, to remove a share we could use the delete method of the Win32_Share WMI class as illustrated earlier when we were examining the Invoke-WmiMethod cmdlet. But we could also perform the query to find the class, and pipeline the resulting WMI object to the Remove-WmiObject cmdlet as shown here. You may prefer this syntax for simplicity’s sake:

Get-WmiObject -Class win32_share -Filter "name = 'fso'" | Remove-WmiObject

Set-WmiInstance: Creates or modifies instances of WMI classes. You use the SetWmiInstance cmdlet in places where you would have used the SpawnInstance method from within VBScript. Here we create a new environmental variable by using the WMI class Win32_Environment. Because the class has no methods, in order to create a new environmental variable, we need to create a new instance of the class. This is easy to do using the Set-WmiInstance cmdlet. The only tricky part is the way the arguments parameter needs to be specified: We use a hash table. Each property from the Win32_Environment WMI class that we need to assign a value to becomes a key value within the hash table. This code is shown here:

Set-WmiInstance -class win32_environment -arguments ` @{Name="testvar";VariableValue="testvalue";UserName="<SYSTEM>"}

 

Event Log Cmdlets

One area that has historically been a problem for network administrators is dealing with event logs. This problem became even more severe with the introduction of Windows Vista and the new types of event logs as well as keeping up with the sheer numbers of the logs. A number of the new cmdlets are designed to address these concerns.

Clear-EventLog: Deletes all entries from specified event logs on the local or remote computers. In this example, we clear the contents of the application log on the local computer:

Clear-EventLog -LogName application


Get-Event:
Gets events from event logs and event tracing log files on local and remote computers. This cmdlet runs only on Windows Vista and later versions of Windows. As seen in the following image, Windows Vista and later versions of Windows have many diagnostic logs:

Image of Windows diagnostic logs


The actual names for these diagnostic logs can be rather long; the name of the log in the previous image is "Microsoft-Windows-Bits-Client/operational." The easiest way to refer to the logs is by using a wildcard character as seen here:

Get-Event -LogName *bits*

As a best practice, I recommend that you use the Get-EventLog cmdlet when accessing the classic event logs. Use Get-Event when working with the newer diagnostic and tracing logs.

Limit-EventLog: Sets the event log properties that limit the size of the event log and the age of its entries on a local or remote computer. To set the retention policy for a computer, use the retention parameter as seen here:

Limit-EventLog -LogName application -Retention 8


New-EventLog:
Creates a new event log and a new event source on a local or remote computer. To create a new event log, you need to specify both a name and a source for the log. If you leave out the computername, it is assumed to be local. In this example, we create a new event log named forScripting with a named source called ScriptErrors. This log will be created on a remote computer named berlin. The custom event log created by this command is seen in the next image.

New-EventLog -LogName forScripting -Source ScriptErrors -ComputerName berlin

Image of custom event log


Remove-EventLog:
Deletes an event log or unregisters an event source on a local or remote computer. To remove an event log, use the Remove-EventLog cmdlet to specify the log name and the computer name if applicable. This code is shown here:

Remove-EventLog -LogName forscripting –computername berlin


Show-EventLog:
Displays the event logs of the local or a remote computer in Event Viewer. This command is the same as typing eventvwr inside the Windows PowerShell console. To use the Show-EventLog cmdlet, you type the name of the cmdlet and specify the name of the computer whose event logs you wish to display in the Event Viewer console. This is illustrated here:

Show-EventLog  -ComputerName berlin


Write-EventLog:
Writes an event to an event log:

Write-EventLog -LogName forScripting -EventId 1000 -Source ScriptErrors `

-EntryType information -Message "Script Completed" –ComputerName berlin


RC, we hope you enjoyed this quick overview of some of the new cmdlets that are available in Windows PowerShell 2.0. Tomorrow we will continue our overview of Windows PowerShell 2.0.

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, keep on scripting!

Ed Wilson and Craig Liebendorfer, Scripting Guys