Removing Computers from SCCM Collection

Below is a simple little script that removes a computer from SCCM collection. The script works fine removing one computer at a time. I would like to have the option of removing one or multiple computers. I was wondering if there is a way to have the script read a list of computers from a text file and remove the computers from the collection. In addition to reading from a text file, I would like to also be able to remove computers by typing a computer name directly on the screen or multiple computer names on the screen separated comma. Thanks!

Script:

$username =“domain\user”
$password = “mypassword!”
$Computername = Read-Host “Type a Computer Name”
$secstr= new-object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $secstr

$compObject = get-wmiobject -query “select * from SMS_R_SYSTEM WHERE Name=‘$Computername’” -computername myofficecomputer -Credential $cred -namespace “ROOT\SMS\site_HH1”

$compObject.psbase.delete()

Maybe something like this can help. By the way, I did not test this:

Param
(
	[String]$Computername:$env:computername
)

$username ="domain\user"
$password = "mypassword!"

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$secstr= new-object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $secstr
	
If ($Computername -eq "ComputerList")
{
	[void][System.Windows.Forms.Messagebox]::Show("Add the computer name(s) to the 'ComputerList.txt' file, then save and close it.", "Add Computer Name(s) to ComputerList.txt") 
	New-Item -Path "$env:TEMP\ComputerList.txt"
	Invoke-Item -Path "$env:TEMP\ComputerList.txt"
	[void][System.Windows.Forms.Messagebox]::Show("Click the OK button to continue")

	$ComputerList = Get-Content -Path "$env:TEMP\ComputerList.txt"

	Foreach ($Computername in $ComputerList)
	{
		$compObject = get-wmiobject -query "select * from SMS_R_SYSTEM WHERE Name='$Computername'" -computername myofficecomputer -Credential $cred -namespace "ROOT\SMS\site_HH1" 

		$compObject.psbase.delete()
	}
}

ElseIf ($Computername -ne "ComputerList")
{
	Foreach ($Computer in $Computername)
	{
		$compObject = get-wmiobject -query "select * from SMS_R_SYSTEM WHERE Name='$Computername'" -computername myofficecomputer -Credential $cred -namespace "ROOT\SMS\site_HH1" 

		$compObject.psbase.delete()
	}
}

So, let’s say you named your script something like Remove-SCCMComputerfromCollection (big name, I know).

Examples:

Single Computer at the PS Prompt

Remove-SCCMComputerfromCollection -Computername “myofficecomputer”

Multiple Computers at the PS Prompt

Remove-SCCMComputerfromCollection -Computername @(“myofficecomputer1”, “myofficecomputer2”, “myofficecomputer3”)

Reading Computers from a Text File List

Remove-SCCMComputerfromCollection -Computername “ComputerList”

This will create the ComputerList.txt file in your TEMP dir and open it up for you to input computer names into. Then once you save and close it, the script should resume.

If you do NOT give the $Computername parameter a value, it will assume the local computer. If you do not want this, then just remove the $env:computername.

gwmi -ComputerName SCCMCOMPUTER -Namespace root\sms\site_SCCM -query “select * from sms_r_system where name=‘servername’”
this give two computer object, how I can delete that ?

First and foremost please clarify if you are intending on removing the computer from SCCM or from a specific SCCM Collection?
Your sample code removes the computer from SCCM not a collection. But it does not uninstall the client so the system can re-register. This may appear to remove a system from a collection if it was a direct member but the old direct membership rule would still remain.
To remove a client from a collection will depend on the membership rules used for the specific collection. A direct rule would simply need to be removed. A query rule would need to be updated so the computer would no longer be included in the results.

The SCCM powershell commandlets can simplify what the sample script is doing

Remove-CMDevice -DeviceName "myofficecomputer"

Remove-CMDevice -DeviceName "myofficecomputer1","myofficecomputer2"

thanks jonathan for your input,remove-cmdevice is not working properly, so I moved to above wql query, above wql works perfect if we get one computer object but it’s not working if we get multiple computer object for same computer .fyi, i am trying to delete and restage computer for osd deployment. so.it can pick the latest osd task sequence.

It all makes sense now :). You are trying to remove the computer record not removing the system from a collection. Because the computer name is not required to be unique it is possible to get multiple values back when querying by name. When this occurs you will need to remove all values or inspect each one to determine which needs to be deleted.
This will delete all of the returned objects

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

In most cases you should not need to do this if the collections where you deploy the OSD task sequence are query based and the update membership schedule is frequent enough. I have my OSD collections update every 30 - 45 minutes so if a tech just waits a bit and tries again every thing starts moving again usually before they can get an admin to delete the computer.

cool Jonathan, thanks agian. I tried syncroot too, it throwed error "not able to find $_psbase.delete()"but any way some how after some time I got only one object. so not sure how or what’s the deal is but I will troubleshoot more if I get this again. FYI, I am not SME in sccm.