Add to Technorati Favorites
Welcome to ThePowerShellGuy.com Sign in | Join | Help

PowerShell : Using Windows Remote Management with alternate credentials to retrieve services

 

As you could see in my last post : My First WinRM PowerShell Script , I started playing with WinRM in this post how to retrieve a list of services on a remote computer, often youcan not do this with your current user account 

So we want to connect to a remote server to list the services, and need other credentials First the credentials

we will see there is a helper method for this but I ran into some problems with using it :

PoSH> $wa = New-Object -ComObject Wsman.Automation                                                                      
PoSH> $wa.c                                                                                                             
PoSH>     ╔═ $wa.c ══════════════════════╗                                                                              
PoSH>      $wa.CreateConnectionOptions(                                                                               
PoSH>      $wa.CreateResourceLocator(                                                                                 
PoSH>      $wa.CreateSession(                                                                                         
PoSH>      $wa.CommandLine                                                                                            
PoSH>     ╚═[1] 1-4 (4/25)]══════════════╝                                                                              
PoSH> $options = $wa.CreateConnectionOptions()                                                                          
PoSH> $Options = $wa.CreateConnectionOptions()                                                                          
PoSH> $options.username = 'foo'                                                                                         
PoSH> $options.Password = 'bar'                                                                                         
Exception setting "Password": "Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"               
At line:1 char:10                                                                                                       
+ $options.P <<<< assword = 'bar'                                                                                       
PoSH>                                                                                 

 

the problem we can find here : WSMan.CreateSession and here ConnectionOptions

Password Data type: BSTR
Access type: Write-only

Sets the password of a local or domain account on the remote computer.

I can see to be able to set it from powerShell, I made the following workaround using the MSScriptControl COM object, to do the same from VbScriptCode that enables me to just throw a string into it :

 

Function Get-WinRmCredentials ([Management.Automation.PSCredential]$cred = (Get-Credential)) {
  $vbs = new-object -com MSScriptControl.ScriptControl
  $vbs.language = 'vbscript'
  $VBS.ExecuteStatement('Set objWsman = CreateObject( "WSMAN.Automation" )')
  $VBS.ExecuteStatement('Set objOptions = objWSMan.CreateConnectionOptions')
  $VBS.ExecuteStatement("objOptions.userName = ""$($cred.GetNetworkCredential().username)""")
  $VBS.ExecuteStatement("objOptions.Password = ""$($cred.GetNetworkCredential().Password)""")
  $VBS.eval('objOptions')
}

 

This function will take a PSCredential object as input or fires the  Get-credential Cmdlet to ask for one So we can ask convert a PowerShell credentials object  to an WinRM ConnectionObject where name and password are filled for the PsCredentials object :

Cred

 

PoSH> $rmCred = Get-WinRmCredentials                                                                                    
                                                                                                                        
cmdlet Get-Credential at command pipeline position 1                                                                    
Supply values for the following parameters:                                                                             
Credential                                                                                                              
PoSH> $rmCred                                                                                                           
                                                                                                                        
UserName                                                    Password                                                    
--------                                                    --------                                                    
foo                                                                                                                     
                                                                                                                        
                                                                                                                        
PoSH>                                                                    

 

and we can use the returned object to connect to WinRM but what we also is provide a Flag :

We can look at the Object to see what Flags are available and what is there value :

 

PoSH> $wa.S                                                                                                             
PoSH>      ╔═ $wa.S ══════════════════════════════╗                                                                     
PoSH>       $wa.SessionFlagCredUsernamePassword(                                                                      
PoSH>       $wa.SessionFlagEnableSPNServerPort(                                                                       
PoSH>       $wa.SessionFlagNoEncryption(                                                                              
PoSH>       $wa.SessionFlagSkipCACheck(                                                                               
PoSH>       $wa.SessionFlagSkipCNCheck(                                                                               
PoSH>       $wa.SessionFlagUseBasic(                                                                                  
PoSH>       $wa.SessionFlagUseDigest(                                                                                 
PoSH>       $wa.SessionFlagUseKerberos(                                                                               
PoSH>       $wa.SessionFlagUseNegotiate(                                                                              
PoSH>       $wa.SessionFlagUseNoAuthentication(                                                                       
PoSH>       $wa.SessionFlagUTF8(                                                                                      
PoSH>      ╚═[1] 1-11 (11/11)]════════════════════╝                                                                     
PoSH> $wa.SessionFlagCredUsernamePassword()                                                                             
4096                                                                                                                    
PoSH> $wa.CreateSession                                                                                                 
                                                                                                                        
                                                                                                                        
MemberType          : Method                                                                                            
OverloadDefinitions : {IDispatch CreateSession (string, int, IDispatch)}                                                
TypeNameOfValue     : System.Management.Automation.PSMethod                                                             
Value               : IDispatch CreateSession (string, int, IDispatch)                                                  
Name                : CreateSession                                                                                     
IsInstance          : True                                                                                              
                                                                                                                        
                                                                                                                        
                                                                                                                        
PoSH>                                                                                  

OK the value we need for this flag  is 4096 

And now we have the helper objects created and have enough information we can connect to the remote computer to list the services for example :

 

PoSH> $session = $wa.CreateSession('http://longhorn1.poshworks.com',4096,$rmcred) ; $session                                                  
                                                                                                                        
Error                                                                BatchItems                                 Timeout 
-----                                                                ----------                                 ------- 
                                                                             -1                                      -1 
                                                                                                                        
                                                                                                                        
PoSH>                                                                                                                   
PoSH> $ResourceUri = "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service"                           
PoSH> $s= $session.Enumerate($ResourceUri)                                                                              
PoSH> $services = &{do { ([xml]$s.ReadItem()).win32_service } until ($s.AtEndOfStream)}                                 
PoSH> $services  | select -first 5 | ft name,Caption,State                                                              
                                                                                                                        
Name                                    Caption                                 State                                   
----                                    -------                                 -----                                   
AeLookupSvc                             Application Experience                  Running                                 
ALG                                     Application Layer Gateway Service       Stopped                                 
AppHostSvc                              Application Host Helper Service         Running                                 
Appinfo                                 Application Information                 Running                                 
AppMgmt                                 Application Management                  Running                                 
                                                                                                                        
                                                                                                                        
PoSH>                                                                   

for WinRM you need use an URI for the WMI path so we create that in first line  in the second we get the services.

the 3th  line is the workhorse of this script ( or bunch of interactive lines, hmm how you you call that , anyone ? ) :

$services = &{do { ([xml]$s.ReadItem()).win32_service } until ($s.AtEndOfStream)}

this line reads the output from the WinRM call and the same as in the last post I cast the results into XML objects, but this time I a start one level deeper to get rid of the need for using the win32_service property everytime and that enables me to use the PowerShell utilities directly on the resulting collection of XML objects.

you can see how much this interactive working and XML support in PowerShell helps working with WinRM , ok we need to use some embedded  Vbscript to set the credentials, but after wrapping that into a function we are ready to go ....

more later about firing some Posh Commands remotely .  

Enjoy,

Greetings /\/\o\/\/

 PS thanks to Jaykul for help and inspiration

Published Tuesday, July 24, 2007 3:45 PM by MoW

Comments

# re: PowerShell : Using Windows Remote Management with alternate credentials to retrieve services

MOW - excellent as usual.

The is supposed to ba a v1.1 in WinRM for XPSP2.  It's referenced in the SDK docsa but I haven't been able to find it anywhere.

On WS2003 R2 it has to be separately installed from Add Windows Components.  Same is true fro Vista I believe.

Tuesday, July 24, 2007 5:22 PM by jvierra

# re: PowerShell : Using Windows Remote Management with alternate credentials to retrieve services

@ jvierra,

You can find the Beta for WinRM that works on XP on the microsoft connect site

Greetings /\/\o\/\/

Wednesday, July 25, 2007 1:33 AM by MoW

# re: PowerShell : Using Windows Remote Management with alternate credentials to retrieve services

or bunch of interactive lines, hmm how you you call that , anyone ....

session sounds good to me

:)

Wednesday, July 25, 2007 11:28 AM by outcast

# re: PowerShell : Using Windows Remote Management with alternate credentials to retrieve services

The bug that makes setting the write-only property impossible is listed on msconnect; please vote for it here: https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=276495&SiteID=99

- Oisn

Friday, July 27, 2007 5:02 PM by Oisin Grehan
Anonymous comments are disabled