Using COM with Windows PowerShell 1.0
In previous chapters we have have covered the use of the .NET framework from within Windows PowerShell. In this chapter we will look at leveraging Microsoft's Component Object Model (COM) via Windows PowerShell. In particular the issue of launching and interacting with applications and working with the Windows desktop from within PowerShell will be covered.
Listing Available COM Objects
<google>ADSDAQBOX_FLOW</google> COM objects available on a Windows system are all registered in the Windows registry. A complete list of registered objects may be obtained from within Windows PowerShell by writing and calling a function similar to the following:
function com_list { $path = "REGISTRY::HKey_Classes_Root\clsid\*\progid" foreach ($val in dir $path) { $val.getvalue("") } }
The above script will provide an extensive list of the COM objects registered in the Windows registry. A search for a specific match may be performed by piping the output of the function through to the select-string cmdlet. For example, the following command lists any COM objects names containing the word explorer:
PS C:\tmp> com_list | select-string explorer InternetExplorer.Application.1 Shell.Explorer.2 Shell.Explorer.1
As illustrated above, there are three entries in the registry which match the criteria. One of these is Internet Explorer and the others relate to Windows Explorer.
Creating COM Object Instances in Windows PowerShell
New COM object instances are created within Windows PowerShell using the new-object cmdlet combined with the -comobject parameter. This parameter may also be abbreviated to -com. In order to avoid a any ambiguity which may result in a .NET or interop library with the same name being loaded, the -strict switch is also recommended:
new-object -comobject object name -strict
For example, to create new InternetExplorer.Application object:
PS C:\tmp> $iexplore = new-object -com InternetExplorer.Application -strict
Listing the Properties and Methods of a COM Object
Once a new instance of a COM object has been created, it is often useful to find out the methods and properties available for that object. As with .NET objects, this can be achieved using the get-member cmdlet (also available via the gm alias). In the following example, this approach is used to identify the methods and properties of the InternetExplorer.Application object instance created in the previous section of this chapter:
PS C:\tmp> $iexplore | gm TypeName: System.__ComObject#{d30c1661-cdaf-11d0-8a3e-00c04fc9e26e} Name MemberType Definition ---- ---------- ---------- ClientToWindow Method void ClientToWindow (int, int) ExecWB Method void ExecWB (OLECMDID, OLECMDEXECOPT, Variant, Variant) GetProperty Method Variant GetProperty (string) GoBack Method void GoBack () GoForward Method void GoForward () GoHome Method void GoHome () GoSearch Method void GoSearch () Navigate Method void Navigate (string, Variant, Variant, Variant, Variant) Navigate2 Method void Navigate2 (Variant, Variant, Variant, Variant, Variant) PutProperty Method void PutProperty (string, Variant) QueryStatusWB Method OLECMDF QueryStatusWB (OLECMDID) Quit Method void Quit () Refresh Method void Refresh () Refresh2 Method void Refresh2 (Variant) ShowBrowserBar Method void ShowBrowserBar (Variant, Variant, Variant) Stop Method void Stop () AddressBar Property bool AddressBar () {get} {set} Application Property IDispatch Application () {get} Busy Property bool Busy () {get} Container Property IDispatch Container () {get} Document Property IDispatch Document () {get} FullName Property string FullName () {get} FullScreen Property bool FullScreen () {get} {set} Height Property int Height () {get} {set} HWND Property int HWND () {get} Left Property int Left () {get} {set} LocationName Property string LocationName () {get} LocationURL Property string LocationURL () {get} MenuBar Property bool MenuBar () {get} {set} Name Property string Name () {get} Offline Property bool Offline () {get} {set} Parent Property IDispatch Parent () {get} Path Property string Path () {get} ReadyState Property tagREADYSTATE ReadyState () {get} RegisterAsBrowser Property bool RegisterAsBrowser () {get} {set} RegisterAsDropTarget Property bool RegisterAsDropTarget () {get} {set} Resizable Property bool Resizable () {get} {set} Silent Property bool Silent () {get} {set} StatusBar Property bool StatusBar () {get} {set} StatusText Property string StatusText () {get} {set} TheaterMode Property bool TheaterMode () {get} {set} ToolBar Property int ToolBar () {get} {set} Top Property int Top () {get} {set} TopLevelContainer Property bool TopLevelContainer () {get} Type Property string Type () {get} Visible Property bool Visible () {get} {set} Width Property int Width () {get} {set}
Interacting With COM Objects
With the information covered so far in this chapter, it is now possible to begin working with COM objects. Clearly once an instance of an object has been created, it is then possible to begin calling methods and setting properties on the object to make it perform tasks and behave in certain ways. As an example of this in action, we will created an instance of the InternetExplorer.Application object, make it visible on the Windows desktop and navigate to a specific URL:
$iexplorer = new-object -com InternetExplorer.Application -strict # Create instance of IE $iexplorer.Visible = $true # Make it visible on the desktop $iexplorer.navigate2("http://www.techotopia.com") # Navigate to the Techotopia home page
Interacting with the Windows Shell
Windows PowerShell and COM provide a mechanism for interacting with various aspects of the Windows GUI through an object named Shell.Application. By manipulating an instance of this object it is possible to perform such tasks as navigate the file system using Windows Explorer, launch control panel items and cascade and tile windows on the desktop.
As with other COM objects, an instance of the Shell.Application class is instantiated using the new-object cmdlet as follows:
$winshell = new-object -com Shell.Application
Once the object is created a list of methods and properties may once again be obtained using get-member (gm):
PS C:\tmp> $winshell | get-member TypeName: System.__ComObject#{866738b9-6cf2-4de8-8767-f794ebe74f4e} Name MemberType Definition ---- ---------- ---------- AddToRecent Method void AddToRecent (Variant, string) BrowseForFolder Method Folder BrowseForFolder (int, string, int, Variant) CanStartStopService Method Variant CanStartStopService (string) CascadeWindows Method void CascadeWindows () ControlPanelItem Method void ControlPanelItem (string) EjectPC Method void EjectPC () Explore Method void Explore (Variant) ExplorerPolicy Method Variant ExplorerPolicy (string) FileRun Method void FileRun () FindComputer Method void FindComputer () FindFiles Method void FindFiles () FindPrinter Method void FindPrinter (string, string, string) GetSetting Method bool GetSetting (int) GetSystemInformation Method Variant GetSystemInformation (string) Help Method void Help () IsRestricted Method int IsRestricted (string, string) IsServiceRunning Method Variant IsServiceRunning (string) MinimizeAll Method void MinimizeAll () NameSpace Method Folder NameSpace (Variant) Open Method void Open (Variant) RefreshMenu Method void RefreshMenu () ServiceStart Method Variant ServiceStart (string, Variant) ServiceStop Method Variant ServiceStop (string, Variant) SetTime Method void SetTime () ShellExecute Method void ShellExecute (string, Variant, Variant, Variant, Variant) ShowBrowserBar Method Variant ShowBrowserBar (string, Variant) ShutdownWindows Method void ShutdownWindows () Suspend Method void Suspend () TileHorizontally Method void TileHorizontally () TileVertically Method void TileVertically () ToggleDesktop Method void ToggleDesktop () TrayProperties Method void TrayProperties () UndoMinimizeALL Method void UndoMinimizeALL () Windows Method IDispatch Windows () WindowsSecurity Method void WindowsSecurity () WindowSwitcher Method void WindowSwitcher () Application Property IDispatch Application () {get} Parent Property IDispatch Parent () {get}
Now that we have object instance and a list of methods and properties, it is time to start performing some tasks. For example, to invoke Windows Explorer initialized to a specified folder (in this case C:\tmp):
PS C:\tmp> $winshell.explore("C:\tmp")
To cascade all the windows on the desktop:
PS C:\tmp> $winshell.cascadewindows()
Similarly, to tile or minimize all windows:
PS C:\tmp> $winshell.tilevertically() PS C:\tmp> $winshell.minimizeall()
In order to run a control panel item, the ControlPanelItem() method of the object needs to be called with the .cpl file of the required item passed as an argument. A full list of items can be obtained from with the Windows PowerShell environment by issuing the following command:
PS C:\tmp> dir $env:windir\system32 -recurse -include *.cpl Directory: Microsoft.PowerShell.Core\FileSystem::C:\Windows\system32 Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 1/18/2008 11:32 PM 1122304 appwiz.cpl -a--- 1/18/2008 11:32 PM 990208 bthprops.cpl -a--- 1/18/2008 11:32 PM 368640 desk.cpl -a--- 1/18/2008 11:32 PM 2249216 Firewall.cpl -a--- 11/2/2006 2:44 AM 183296 hdwwiz.cpl -a--- 1/18/2008 11:32 PM 1827840 inetcpl.cpl -a--- 1/18/2008 11:32 PM 337408 intl.cpl -a--- 11/2/2006 2:44 AM 418816 irprops.cpl -a--- 11/2/2006 2:44 AM 484864 main.cpl -a--- 1/18/2008 11:32 PM 1102848 mmsys.cpl -a--- 11/2/2006 2:44 AM 164864 ncpa.cpl -a--- 1/18/2008 11:32 PM 163328 powercfg.cpl -a--- 1/18/2008 11:32 PM 242688 sysdm.cpl -a--- 11/2/2006 2:44 AM 106496 telephon.cpl -a--- 1/18/2008 11:32 PM 714240 timedate.cpl
As an example, the following command will display the Windows Display control panel window:
PS C:\tmp> $winshell.controlpanelitem("desk.cpl")
Using the WScript.Shell Class
The WScript.Shell class provides a number of useful utilities that greatly extend the range of tasks that can be performed using Windows PowerShell and COM, such as running applications, sending keystrokes to running applications, changing the current working directory and displaying popup message dialogs.
A WScript.Shell instance is created and a list of available methods and properties displayed as follows:
PS C:\tmp> $wscript = new-object -com wscript.shell PS C:\tmp> $wscript | gm TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090} Name MemberType Definition ---- ---------- ---------- AppActivate Method bool AppActivate (Variant, Variant) CreateShortcut Method IDispatch CreateShortcut (string) Exec Method IWshExec Exec (string) ExpandEnvironmentStrings Method string ExpandEnvironmentStrings (string) LogEvent Method bool LogEvent (Variant, string, string) Popup Method int Popup (string, Variant, Variant, Variant) RegDelete Method void RegDelete (string) RegRead Method Variant RegRead (string) RegWrite Method void RegWrite (string, Variant, Variant) Run Method int Run (string, Variant, Variant) SendKeys Method void SendKeys (string, Variant) Environment ParameterizedProperty IWshEnvironment Environment (Variant) {get} CurrentDirectory Property string CurrentDirectory () {get} {set} SpecialFolders Property IWshCollection SpecialFolders () {get}
The power of the WScript.Shell class is best demonstrated through a simple example. The following script launches the standard Windows Notepad application, waits until the application has started to make it the active application (such that the focus is on the application) and then sends some text to the application:
$wscript.run("notepad") while ($wscript.appactivate("notepad") -ne $true) { "Waiting for app to start...." } $wscript.sendkeys("Hello From Windows PowerShell and COM")
Once executed, Notepad should be running and visible, the currently active application and contain the text which reads "Hello From Windows PowerShell and COM".
Summary
In this chapter we have taken a tour of the basics of using Windows PowerShell in conjunction with the Component Object Model (COM). As with .NET, it should be evident that the availability of COM to the Windows PowerShell developer considerably enhances range of options for performing tasks within the contexts of Windows. Entire books could, and indeed have, been written on COM, so take what you learned in this chapter, grap a COM book from the library and unleash the power that is available to you as a Windows PowerShell programmer.