Created
March 13, 2017 09:54
-
-
Save danjpadgett/8e03151af999b78e2759c10094666efa to your computer and use it in GitHub Desktop.
RemoveObjects.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.NOTES | |
=========================================================================== | |
Created by: Dan Padgett (C) | |
Organization: www.execmgr.net | |
Version: 1.0 | |
=========================================================================== | |
.SYNOPSIS | |
Removal Tool for SCCM and AD Objects | |
.NOTES | |
Script relies on a settings.xml file , the file should look like: | |
<?xml version="1.0" encoding="UTF-8"?> | |
<Settings> | |
<Main> | |
<SCCMServer>sccm.company.group</SCCMServer> | |
<SearchBase>OU=Workstations,OU=Root,DC=company,DC=group</SearchBase> | |
<SystemOUName>COMPANY.GROUP/ROOT/WORKSTATIONS<SystemOUName> | |
<SccmSite>XXX</SccmSite> | |
<cmrcviewer>C:\Program Files (x86)\ConfigMgrConsole\bin\i386\CmRcViewer.exe</cmrcviewer> | |
</Main> | |
</Settings> | |
.DISCLAIMER | |
All scripts are provided AS IS without warranty of any kind. The author further disclaims all implied warranties including, without limitation, | |
any implied warranties of merchantability or of fitness for a particular purpose. | |
The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. | |
In no event shall the author,or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever | |
including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss | |
arising out of the use of or inability to use the sample scripts or documentation, even if the author has been advised of the possibility of such damages. | |
.LINK | |
www.execmgr.net | |
#> | |
#region Control Helper Functions | |
function ConvertTo-DataTable | |
{ | |
[OutputType([System.Data.DataTable])] | |
param( | |
[ValidateNotNull()] | |
$InputObject, | |
[ValidateNotNull()] | |
[System.Data.DataTable]$Table, | |
[switch]$RetainColumns, | |
[switch]$FilterWMIProperties) | |
if($Table -eq $null) | |
{ | |
$Table = New-Object System.Data.DataTable | |
} | |
if($InputObject-is [System.Data.DataTable]) | |
{ | |
$table = ConvertTo-DataTable -InputObject $processes –FilterWMIProperties | |
} | |
else | |
{ | |
if(-not $RetainColumns -or $Table.Columns.Count -eq 0) | |
{ | |
#Clear out the Table Contents | |
$Table.Clear() | |
if($InputObject -eq $null){ return } #Empty Data | |
$object = $null | |
#find the first non null value | |
foreach($item in $InputObject) | |
{ | |
if($item -ne $null) | |
{ | |
$object = $item | |
break | |
} | |
} | |
if($object -eq $null) { return } #All null then empty | |
#Get all the properties in order to create the columns | |
foreach ($prop in $object.PSObject.Get_Properties()) | |
{ | |
if(-not $FilterWMIProperties -or -not $prop.Name.StartsWith('__'))#filter out WMI properties | |
{ | |
#Get the type from the Definition string | |
$type = $null | |
if($prop.Value -ne $null) | |
{ | |
try{ $type = $prop.Value.GetType() } catch {} | |
} | |
if($type -ne $null) # -and [System.Type]::GetTypeCode($type) -ne 'Object') | |
{ | |
[void]$table.Columns.Add($prop.Name, $type) | |
} | |
else #Type info not found | |
{ | |
[void]$table.Columns.Add($prop.Name) | |
} | |
} | |
} | |
if($object -is [System.Data.DataRow]) | |
{ | |
foreach($item in $InputObject) | |
{ | |
$Table.Rows.Add($item) | |
} | |
return @(,$Table) | |
} | |
} | |
else | |
{ | |
$Table.Rows.Clear() | |
} | |
foreach($item in $InputObject) | |
{ | |
$row = $table.NewRow() | |
if($item) | |
{ | |
foreach ($prop in $item.PSObject.Get_Properties()) | |
{ | |
if($table.Columns.Contains($prop.Name)) | |
{ | |
$row.Item($prop.Name) = $prop.Value | |
} | |
} | |
} | |
[void]$table.Rows.Add($row) | |
} | |
} | |
return @(,$Table) | |
} | |
function Load-DataGridView | |
{ | |
Param ( | |
[ValidateNotNull()] | |
[Parameter(Mandatory=$true)] | |
[System.Windows.Forms.DataGridView]$DataGridView, | |
[ValidateNotNull()] | |
[Parameter(Mandatory=$true)] | |
$Item, | |
[Parameter(Mandatory=$false)] | |
[string]$DataMember | |
) | |
Load-DataGridView -DataGridView $datagridviewResults -Item $table | |
$DataGridView.SuspendLayout() | |
$DataGridView.DataMember = $DataMember | |
if ($Item -is [System.ComponentModel.IListSource]` | |
-or $Item -is [System.ComponentModel.IBindingList] -or $Item -is [System.ComponentModel.IBindingListView] ) | |
{ | |
$DataGridView.DataSource = $Item | |
} | |
else | |
{ | |
$array = New-Object System.Collections.ArrayList | |
if ($Item -is [System.Collections.IList]) | |
{ | |
$array.AddRange($Item) | |
} | |
else | |
{ | |
$array.Add($Item) | |
} | |
$DataGridView.DataSource = $array | |
} | |
$DataGridView.ResumeLayout() | |
} | |
#endregion | |
#region Variables | |
#Load Settings from setting.xml | |
[xml]$ConfigFile = Get-Content ".\Settings.xml" | |
$sccmserver = $ConfigFile.Settings.Main.SCCMServer | |
$searchbase = $ConfigFile.Settings.Main.SearchBase | |
$SystemOUName = $ConfigFile.Settings.Main.SystemOUName | |
$sccmsite = $ConfigFile.Settings.Main.SccmSite | |
$cmrcviewer = $ConfigFile.Settings.Main.cmrcviewer | |
#endregion | |
$textboxSearch.Text = $SystemOUName | |
function ColorCells | |
{ | |
$i = -0 | |
foreach ($row in $datagridviewResults.Rows) | |
{ | |
if ($datagridviewResults.Rows[$i].Cells['SCCMResourceID'].Value -eq $null) | |
{ | |
$row.defaultcellstyle.backcolor = 'yellow' | |
} | |
else | |
{ | |
##//Do not color cells | |
} | |
##//Increment $i | |
$i++ | |
} | |
} | |
$formMain_Load = { | |
#TODO: Initialize Form Controls here | |
$UserContextText.Text = "Running As: $env:USERDOMAIN\$env:USERNAME" | |
#//test for settins.xml file | |
if (!(Test-Path .\settings.xml)) | |
{ | |
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | |
[System.Windows.Forms.MessageBox]::Show("Could not find Settings.xml , please create it and try again", "Error", 0) | |
$formMain.Close() | |
} | |
} | |
function New-ObjectSearch | |
{ | |
param ( | |
$sccmArr | |
) | |
[System.Collections.ArrayList]$computers = Get-ADComputer -Filter * -property name, Description, OperatingSystem, IPv4Address, ms-MCS-AdmPwd -SearchBase $searchbase | select Name, Description, OperatingSystem, IPv4Address, Enabled, @{ Name = "LAPS Password"; Expression = { ($_.'ms-MCS-AdmPwd') } } | sort name | |
$computers | ForEach { | |
$compname = $_.Name | |
$_ | Add-Member -MemberType NoteProperty -Name MACAddresses -Value ($sccmArr | Where-Object { $_.name -eq $compname } | Select-Object -ExpandProperty MACAddresses | Select-Object -First 1) | |
$_ | Add-Member -MemberType NoteProperty -Name SCCMResourceID -Value ($sccmArr | Where-Object { $_.name -eq $compname } | Select-Object -ExpandProperty ResourceID) | |
} | |
return $computers | |
} | |
[System.Collections.ArrayList]$sccmQuery = get-wmiobject -query "select * from SMS_R_SYSTEM WHERE Name like '%' " -computername $sccmserver -namespace "ROOT\SMS\site_$sccmsite" | Where-Object { $_.SystemOUName -contains $SystemOUName } | |
#region Search Function | |
function SearchGrid() | |
{ | |
$RowIndex = 0 | |
$ColumnIndex = 0 | |
$seachString = $textboxSearch.Text | |
if($seachString -eq "") | |
{ | |
return | |
} | |
if($datagridviewResults.SelectedCells.Count -ne 0) | |
{ | |
$startCell = $datagridviewResults.SelectedCells[0]; | |
$RowIndex = $startCell.RowIndex | |
$ColumnIndex = $startCell.ColumnIndex + 1 | |
} | |
$columnCount = $datagridviewResults.ColumnCount | |
$rowCount = $datagridviewResults.RowCount | |
for(;$RowIndex -lt $rowCount; $RowIndex++) | |
{ | |
$Row = $datagridviewResults.Rows[$RowIndex] | |
for(;$ColumnIndex -lt $columnCount; $ColumnIndex++) | |
{ | |
$cell = $Row.Cells[$ColumnIndex] | |
if($cell.Value -ne $null -and $cell.Value.ToString().IndexOf($seachString, [StringComparison]::OrdinalIgnoreCase) -ne -1) | |
{ | |
$datagridviewResults.CurrentCell = $cell | |
return | |
} | |
} | |
$ColumnIndex = 0 | |
} | |
$datagridviewResults.CurrentCell = $null | |
[void][System.Windows.Forms.MessageBox]::Show("The search has reached the end of the grid.","String not Found") | |
} | |
#endregion | |
#region Events | |
#//Remote Control | |
$buttonRemoteControl_Click = { | |
if ( $($datagridviewResults.CurrentCell.Value.ToString()) -notin $sccmQuery.Name ) | |
{ | |
[System.Windows.Forms.MessageBox]::Show("Please select item from Name column", "Error", 0) | |
#donothing | |
} | |
else | |
{ | |
& $CmRcViewer $($datagridviewResults.CurrentCell.Value.ToString()) | |
} | |
} | |
##//Remove AD Object | |
$buttonRemoveAD_Click = { | |
if ($($datagridviewResults.CurrentCell.Value.ToString()) -notin $sccmQuery.Name) | |
{ | |
[System.Windows.Forms.MessageBox]::Show("Please select item from Name column", "Error", 0) | |
#donothing | |
} | |
else | |
{ | |
$selecteditem = $($datagridviewResults.CurrentCell.Value.ToString()) | |
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | |
$msgboxwarning = [System.Windows.Forms.MessageBox]::Show("Are you sure you want to remove '$selecteditem' from Active Directory?", "Confirm Removal", 1) | |
if ($msgboxwarning -eq "OK") | |
{ | |
Remove-ADComputer -Identity $selecteditem -confirm:$false | |
} | |
else | |
{ | |
#donothing | |
} | |
} | |
} | |
##//Remove SCCM Object | |
$buttonRemoveSCCMObject_Click = { | |
if ($($datagridviewResults.CurrentCell.Value.ToString()) -notin $sccmQuery.Name) | |
{ | |
[System.Windows.Forms.MessageBox]::Show("Please select item from Name column", "Error", 0) | |
#donothing | |
} | |
else | |
{ | |
$selecteditem = $($datagridviewResults.CurrentCell.Value.ToString()) | |
$compobject = $sccmQuery | Where-Object { $_.Name -eq $selecteditem } | |
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | |
$msgboxwarning = [System.Windows.Forms.MessageBox]::Show("Are you sure you want to remove '$selecteditem' - SCCM Resource ID :$($compObject.ResourceID)", "Confirm Removal", 1) | |
if ($msgboxwarning -eq "OK") | |
{ | |
$toolstripstatuslabel1.Text = "Removing SCCM Object...." | |
$compObject.psbase.delete() | |
timeout 2 | |
##Clear removed SCCM Resource out of Array. | |
for ($i = 0; $i -lt $sccmQuery.Count; $i++) | |
{ | |
if ($sccmQuery[$i].Name -eq $selecteditem) | |
{ | |
Write-Host "$($sccmQuery[$i].Name)" | |
$sccmQuery.RemoveAt($i) | |
$toolstripstatuslabel1.Text = "Successfully removed SCCM Object...." | |
} | |
} | |
$datagridviewResults.Refresh() | |
$computerArr = New-ObjectSearch $sccmQuery | |
Load-DataGridView -DataGridView $datagridviewResults -Item $computerArr -ErrorAction SilentlyContinue | |
ColorCells | |
} | |
elseif ($msgboxwarning -eq "Cancel") | |
{ | |
#donothing | |
} | |
} | |
} | |
##//Remove SCCM and AD Object | |
$buttonRemoveSCCMADObject_Click = { | |
if ($($datagridviewResults.CurrentCell.Value.ToString()) -notin $sccmQuery.Name) | |
{ | |
[System.Windows.Forms.MessageBox]::Show("Please select item from Name column", "Error", 0) | |
#donothing | |
} | |
else | |
{ | |
$selecteditem = $($datagridviewResults.CurrentCell.Value.ToString()) | |
$compobject = $sccmQuery | Where-Object { $_.Name -eq $selecteditem } | |
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | |
$msgboxwarning = [System.Windows.Forms.MessageBox]::Show("Are you sure you want to remove '$selecteditem' - SCCM Resource ID : $($compObject.ResourceID) & from AD", "Confirm Removal", 1) | |
if ($msgboxwarning -eq "OK") | |
{ | |
##//Remove SCCM Object from DB | |
$toolstripstatuslabel1.Text = "Removing SCCM & AD Object...." | |
$compObject.psbase.delete() | |
timeout 2 | |
##Clear removed SCCM Resource out of Array. | |
for ($i = 0; $i -lt $sccmQuery.Count; $i++) | |
{ | |
if ($sccmQuery[$i].Name -eq $selecteditem) | |
{ | |
Write-Host "$($sccmQuery[$i].Name)" | |
$sccmQuery.RemoveAt($i) | |
$toolstripstatuslabel1.Text = "Successfully removed SCCM Object...." | |
} | |
} | |
##/ | |
##//Remove AD Object | |
Remove-ADComputer -Identity $selecteditem -confirm:$false | |
##/ | |
$datagridviewResults.Refresh() | |
$computerArr = New-ObjectSearch $sccmQuery | |
Load-DataGridView -DataGridView $datagridviewResults -Item $computerArr -ErrorAction SilentlyContinue | |
ColorCells | |
} | |
} | |
} | |
##//Search Controls | |
$textboxSearch_KeyDown = [System.Windows.Forms.KeyEventHandler]{ | |
#Event Argument: $_ = [System.Windows.Forms.KeyEventArgs] | |
if ($_.KeyCode -eq 'Enter' -and $buttonSearchFilter.Enabled) | |
{ | |
#ObjectSearch | |
$computerArr = New-ObjectSearch $sccmQuery | |
SearchGrid | |
$_.SuppressKeyPress = $true | |
} | |
} | |
##//Exit Controls | |
$buttonExit_Click = { | |
#TODO: Place custom script here | |
$formMain.Close() | |
} | |
##//Search Event | |
$buttonSearchFilter_Click = { | |
$datagridviewResults.Refresh() | |
$computerArr = New-ObjectSearch $sccmQuery | |
Load-DataGridView -DataGridView $datagridviewResults -Item $computerArr -ErrorAction SilentlyContinue | |
$toolstripstatuslabel1.Text = "Select Object (From NAME Column)" | |
SearchGrid | |
ColorCells | |
} | |
$datagridviewResults_ColumnHeaderMouseClick = [System.Windows.Forms.DataGridViewCellMouseEventHandler]{ | |
#Event Argument: $_ = [System.Windows.Forms.DataGridViewCellMouseEventArgs] | |
if ($datagridviewResults.DataSource -is [System.Data.DataTable]) | |
{ | |
$column = $datagridviewResults.Columns[$_.ColumnIndex] | |
$direction = [System.ComponentModel.ListSortDirection]::Ascending | |
if ($column.HeaderCell.SortGlyphDirection -eq 'Descending') | |
{ | |
$direction = [System.ComponentModel.ListSortDirection]::Descending | |
} | |
$datagridviewResults.Sort($datagridviewResults.Columns[$_.ColumnIndex], $direction) | |
} | |
} | |
$formMain_FormClosed = [System.Windows.Forms.FormClosedEventHandler]{ | |
#Event Argument: $_ = [System.Windows.Forms.FormClosedEventArgs] | |
#Stop any pending jobs | |
Stop-JobTracker | |
} | |
#endregion | |
#region Job Tracker | |
$timerJobTracker_Tick = { | |
Update-JobTracker | |
} | |
$JobTrackerList = New-Object System.Collections.ArrayList | |
function Add-JobTracker | |
{ | |
Param ( | |
[ValidateNotNull()] | |
[Parameter(Mandatory = $true)] | |
[string]$Name, | |
[ValidateNotNull()] | |
[Parameter(Mandatory = $true)] | |
[ScriptBlock]$JobScript, | |
$ArgumentList = $null, | |
[ScriptBlock]$CompletedScript, | |
[ScriptBlock]$UpdateScript) | |
#Start the Job | |
$job = Start-Job -Name $Name -ScriptBlock $JobScript -ArgumentList $ArgumentList | |
if ($job -ne $null) | |
{ | |
#Create a Custom Object to keep track of the Job & Script Blocks | |
$members = @{ | |
'Job' = $Job; | |
'CompleteScript' = $CompletedScript; | |
'UpdateScript' = $UpdateScript | |
} | |
$psObject = New-Object System.Management.Automation.PSObject -Property $members | |
[void]$JobTrackerList.Add($psObject) | |
#Start the Timer | |
if (-not $timerJobTracker.Enabled) | |
{ | |
$timerJobTracker.Start() | |
} | |
} | |
elseif ($CompletedScript -ne $null) | |
{ | |
#Failed | |
Invoke-Command -ScriptBlock $CompletedScript -ArgumentList $null | |
} | |
} | |
function Update-JobTracker | |
{ | |
<# | |
.SYNOPSIS | |
Checks the status of each job on the list. | |
#> | |
#Poll the jobs for status updates | |
$timerJobTracker.Stop() #Freeze the Timer | |
for ($index = 0; $index -lt $JobTrackerList.Count; $index++) | |
{ | |
$psObject = $JobTrackerList[$index] | |
if ($psObject -ne $null) | |
{ | |
if ($psObject.Job -ne $null) | |
{ | |
if ($psObject.Job.State -ne "Running") | |
{ | |
#Call the Complete Script Block | |
if ($psObject.CompleteScript -ne $null) | |
{ | |
#$results = Receive-Job -Job $psObject.Job | |
Invoke-Command -ScriptBlock $psObject.CompleteScript -ArgumentList $psObject.Job | |
} | |
$JobTrackerList.RemoveAt($index) | |
Remove-Job -Job $psObject.Job | |
$index-- #Step back so we don't skip a job | |
} | |
elseif ($psObject.UpdateScript -ne $null) | |
{ | |
#Call the Update Script Block | |
Invoke-Command -ScriptBlock $psObject.UpdateScript -ArgumentList $psObject.Job | |
} | |
} | |
} | |
else | |
{ | |
$JobTrackerList.RemoveAt($index) | |
$index-- #Step back so we don't skip a job | |
} | |
} | |
if ($JobTrackerList.Count -gt 0) | |
{ | |
$timerJobTracker.Start() #Resume the timer | |
} | |
} | |
function Stop-JobTracker | |
{ | |
<# | |
.SYNOPSIS | |
Stops and removes all Jobs from the list. | |
#> | |
#Stop the timer | |
$timerJobTracker.Stop() | |
#Remove all the jobs | |
while ($JobTrackerList.Count -gt 0) | |
{ | |
$job = $JobTrackerList[0].Job | |
$JobTrackerList.RemoveAt(0) | |
Stop-Job $job | |
Remove-Job $job | |
} | |
} | |
#endregion | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment