Powser Shell Script to Purge Computer Records from SCCM

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of Tony Chirillo Tony Chirillo 2 years, 1 month ago.

  • Author
    Posts
  • #19833
    Profile photo of Tony Chirillo
    Tony Chirillo
    Participant

    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.

    http://marco-difeo.de/2011/08/02/sccm-delete-computer-object-via-powershell-and-wmi/comment-page-1/#comment-31831

    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: (:) [], 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() }

    }

  • #19845
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

  • #19856
    Profile photo of Tony Chirillo
    Tony Chirillo
    Participant

    Dave

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

    –Tony

You must be logged in to reply to this topic.