Thursday, January 12, 2012

Operation is not valid due to the current state of the object.

I was working on this PowerShell script, pulling DHCP scopes and their registered entries, DNS forward and reverse lookup records, and deleting them based on scpecific criteria. The script cleans DNS by checking agains DHCP records and any DNS record not found in the list for each scope gets deleted, same goes for expired, or with a different "OwnerName". This was needed because anomalities in DNS entries for supposedly static records kept us from turning on scavenging without removing some servers. We thought this was best way to filter them out.

There I am, going crazy with powershell, creating a complicated script, getting WMI objects and filtering per our needs. Using hashtables of hashtables, hashtables of arrays of objects, calling functions to check against other objects or lists. Then after a few days of coding and searching online how to best do it, right when I tried to delete one record as a test:
Exception calling "Delete" with "0" argument(s): "Operation is not valid due to the current state of the object."
At line:1 char:22
+ $result | %{$_.Delete <<<< ()}
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
What!? Don't tell me I cant delete them now! Why?
I went searching for that error, looked at several howtos, tutorials, forumns, etc. Nothing mentioned seemed to be the problem I was having. Eventually through trial and error I figured it out.
I had this code:
Get-WMIObject -Computer $Server -Namespace "root\MicrosoftDNS" -Class "MicrosoftDNS_AType" `
 -Filter "ContainerName='$($Domain)' AND OwnerName<>'$($Domain)'" `
 -Property @("OwnerName", "IPAddress", "Timestamp")
In oder to delete the record or modify it, you need to have the "FULL" object. The fix was to remove the property selection code, so I ended up with:
Get-WMIObject -Computer $Server -Namespace "root\MicrosoftDNS" -Class "MicrosoftDNS_AType" `
 -Filter "ContainerName='$($Domain)' AND OwnerName<>'$($Domain)'"
That worked.

Another thing to watch out for is that for whatever reason the above filtering commands wont work if you use "like, is, not, etc." in your "-Filter" property.

Happy PShelling!

Marlon