Powser Shell Script to Purge Computer Records from SCCM

I am building a PowerShell Script to obtain the names of the computer resources stored in a SCCM 2012 collection and place them in a variable. Next, I want to obtain the computer resources (e.g., ddr records) and store them in a 2ed variable using the first variable to pipe in the data. I am using a “ForEach” looping construct to accomplish this. Lastly, I want to purge the computers records from the Configuration Manager database that are stored in the second variable which came from the computers names of the specified SCCM collection. I am attempting to use this line of code within my loop to purge the computer records from SCCM:

$compObject.psbase.syncroot | % { $_.psbase.delete() }

Here is a blog I found suggesting this line of code.

What I have discovered is rather interesting. My script works as intended, but even though the correct records ARE being purged. The above line of code is returning an error.

You cannot call a method on a null-valued expression.
At line:18 char:35

  • $compObject.psbase.syncroot | % { $_.psbase.delete() }
  •                               ~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (:slight_smile: , RuntimeException
    • FullyQualifiedErrorId : InvokeMethodOnNull

I have a few questions:

  1. Does anyone know why this is occurring?
  2. Is there a different approach or code I should be using instead to purge the collected data?

Here is my full script:
#// required parameters
$SCCMServer = “doit-sccm-site”
$sitename = “PS1”
$collectionID = “PS1009c8”

#// Obtain collection members from $collectionID
$SMSClients = Get-WmiObject -Query “SELECT * FROM SMS_FullCollectionMembership WHERE CollectionID=‘$collectionID’ order by name” -ComputerName $SCCMServer -Namespace “ROOT\SMS\site_$sitename”

#//looping construct to loop through all the colection members
ForEach ($SMSclient in $SMSclients) {

#// Loads computer records one at a time into $compobject variable using a ForEachloop to be deleted
$compObject = get-wmiobject -query “select * from SMS_R_SYSTEM WHERE Name=‘$($smsclient.name)’” -computername $SCCMServer -namespace “ROOT\SMS\site_$sitename”

#// Delete’s computer objects one at a time in $compObject variable from CM12 database

$compObject.psbase.syncroot | % { $_.psbase.delete() }

}

I’m not sure why that article is messing with the SyncRoot property. You could just do this, and it should work whether Get-WmiObject returns zero, one or multiple results:

Get-WmiObject -query "select * from SMS_R_SYSTEM WHERE Name='$($smsclient.name)'" -computername $SCCMServer -namespace "ROOT\SMS\site_$sitename" |
ForEach-Object { $_.Delete() }

You can store the results of Get-WmiObject into a variable if you like, but it’s probably not necessary. You also don’t have to use .PSBase in most situations, so I took that out and just called $_.Delete() . Let me know if you still have problems with the code after that change.

Dave

That’s awesome! Thanks for the advice. Your suggestion worked perfectly, the needed records were deleted and I received no errors!

–Tony