Posts tagged PowerShell

Adding Custom Properties to Functions

A question was asked on StackOverflow regarding how to add properties to a function, and then be able to retain that custom property when recalling that function from the function Provider.   I’m not going to copy my answer here, but I do want to throw out a possible work around for this issue. 

(It has been bugging me and I can’t really concentrate on my other tasks, so I need to get this out of the way.)

One suggestion I had was to create a type extension that had the property he was adding, but he was more interested in tagging specific functions, not all of them.

So, I’ve written a couple of little ScriptProperties to save and restore NoteProperties which have been added to FunctionInfo objects.  I’ve added these to a PS1XML.

   1: <?xml version="1.0" encoding="utf-8" ?> 
   2: <Types> 
   3:     <Type> 
   4:         <Name>System.Management.Automation.FunctionInfo</Name> 
   5:         <Members> 
   6:             <ScriptMethod> 
   7:                 <Name>SaveMetadata</Name> 
   8:                 <Script> 
   9: $DefaultProperties = 'PSPath', 'PSDrive', 'PSProvider', 'PSIsContainer'
  10: $SaveDirectory = Split-Path $profile
  11: $File = Join-Path $SaveDirectory "$($this.Name).xml"
  12: $this.PSObject.Properties | Where-Object {$DefaultProperties -notcontains $_.Name -and $_.MemberType -like 'NoteProperty'} | Export-Clixml -Path $file
  13:                 </Script> 
  14:             </ScriptMethod>
  15:             <ScriptMethod> 
  16:                 <Name>LoadMetadata</Name> 
  17:                 <Script> 
  18: $SaveDirectory = split-path $profile
  19: $PathToCustomProp = Join-Path $SaveDirectory "$($this.name).xml"
  20: if (Test-Path $PathToCustomProp)
  21: {
  22:     foreach ($Property in Import-Clixml -Path $PathToCustomProp)
  23:     {
  24:         Add-Member -InputObject $this -MemberType NoteProperty -Name $Property.Name -Value $Property.Value
  25:     }
  26: }
  27:                 </Script> 
  28:             </ScriptMethod> 
  29:         </Members> 
  30:     </Type> 
  31: </Types> 

After saving this file as a PS1XML file, you can call Update-TypeData –Prepend path\to\thefile.ps1xml, and every FunctionInfo object will have two script properties – SaveMetadata and LoadMetadata.  As I’ve configured it, the data will be saved to the user’s profile directory and under a filename that matches the function name.  So, you can add NoteProperties to your heart’s desire and save and recall them as needed. 

I don’t have a direct application for this, and it can probably be cleaned up or done more efficiently, but I had to work through the problem.  I’d love to hear your feedback!

Dealing with WMI Timeouts

There was a question in the PowerShellCommunity.Org forums about WMI timeouts.

I did some digging and found there are several different types of timeouts that can affect your WMI queries.  I’m still working through different scenarios and I’d appreciate any feedback.

The first type of timeout can occur if the machine that you are targeting does not respond to network traffic (it’s down, you have the wrong IP address, firewalled, etc..).  Your WMI call will usually time out after around 20 seconds.

A partial solution to that type of timeout is to ping the machine first.  If you can ping that machine, you’ve eliminated a number of potential problems.  You still might have permission issues or firewall issues, but you are able to reach the machine.

The second time of timeout I’ve seen is when the connection is made, but the WMI call hangs and does not return.

A potential fix for this issue is to use the [WMISearcher] accelerator.  In the options property of the resulting object, there is a ReturnImmediately property, which should be set by default to true.

$searcher = [WMISearcher]”

$searcher.Options.ReturnImmediately

The ReturnImmediately property being set to true requires that the invoked operation (the search) be done synchronously and return immediately.  The enumeration of the results of the WMI call are handled after the return of this operation.

An alternative solution for this issue would be to check the Transaction timeout setting on the target machine.  Run DCOMCnfg.exe and navigate to the Component Services->My Computer.  Right click and choose properties.  On the options tab, there is a timeout (in seconds) for DCOM transactions.  The default value for this setting is 60 seconds.  Fiddle with that at your own risk.  Also, I haven’t had a chance to check for where that value is in the registry or see if there is a Group Policy setting for it.  Setting this value should allow a failed WMI connection to timeout more quickly.

The third area in which I’ve found timeouts/hangs in WMI queries is during the enumeration of the query results.  There is a property in options for the WMI class accelerator called Timeout, which sets the length of time between enumerations before timing out.  The options property is hidden in the default view of PowerShell, so you will need to access it via the psbase property. 

The timeout value is a System.TimeSpan object.  You can specify the value with a TimeSpan object, a number of ticks, or a string that can be cast to a TimeSpan.

It can be set like this:

$wmi = [wmi]”

$wmi.psbase.options.timeout =’0:0:2′ #String that will be cast to a two second TimeSpan

You can also set a timeout value for the [WMISearcher] accelerator.

$searcher = [WMISearcher]”

$searcher.Options.timeout = ’0:0:2′

WMI timeouts can be aggravating, hopefully one of these solutions will help mitigate your WMI woes.

Get Adobe Flash playerPlugin by wpburn.com wordpress themes