Files
Zack Meier 1d304511b8 update
2026-04-15 15:45:50 -05:00

290 lines
12 KiB
PowerShell

<#
.SYNOPSIS
Decomissions a Windows Server device
.DESCRIPTION
Decomissions a Windows Server device with ITD specifications (DNS/Infoblox, Active Directory, SCCM)
.NOTES
Credential must be an nd.gov account with access to remove objects on all platforms involved: DNS/Infoblox, Active Directory, SCCM. Read access to vCenter in the future.
.EXAMPLE
Remove-ITDWindowsServer -ComputerName itdxxx.nd.gov -SCTaskNum SCTASKxxxxxxxxx -Credential $AdminCredential
#>
function Remove-ITDWindowsServer {
[CmdletBinding()]
param (
[string]
$ComputerName,
[string]
$SCTaskNum,
[Parameter(Mandatory = $true)]
[PSCredential]
$Credential
)
begin {
$RadiusCred = New-Object System.Management.Automation.PSCredential($Credential.username.split('\')[1], ($Credential.Password))
}
process {
$HostName = $ComputerName.split('.')[0]
# get current user, SCTask, Ritm, custom variables
switch ($env:username) {
'svcitdiaasauto' {
$assignTo = Get-ITDServiceNowUser -Username svcvmwareadm
}
Default {
$assignTo = Get-ITDServiceNowUser -Username $Env:username
}
}
$SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
$RitmNum = $SCTask.request_item.display_value
Write-Verbose -Message "Gathering $RitmNum"
$Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $RitmNum -IncludeVariableSet -ErrorAction Stop
###### the name in the $ComputerName parameter must match a name in the form to continue
Write-Verbose -Message "Gathering VariableSet data from $RitmNum"
$MatchFound = $false
ForEach ($Row in $Ritm.VariableSet) {
$TempCi = Get-ITDServiceNowRecord -Table cmdb_ci -SysId ($Row.host_name_ref) -ErrorAction Stop
If ($ComputerName -eq $TempCi.FQDN.display_value) {
$Ci = $TempCi
$MatchFound = $true
}
}
$FQDN = $Ci.fqdn.display_value
If ($MatchFound -eq $false) {
Write-Error -Message "ComputerName $ComputerName was not found in VariableSet for $RitmNum" -ErrorAction Stop
}
Write-Verbose -Message "Assigning SCTask to current user, maybe"
##### Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{assigned_to = $assignTo.name } REVIEW IF ASSIGNMENT SHOULD BE MADE HERE
$short_description = $SCTask.short_description.display_value
# Gather DNS FQDN and IP
$DNSResolve = Resolve-DnsName -Name $ComputerName -ErrorAction SilentlyContinue
If ($DNSResolve -eq $null) {
$DNSResolve = "DNS object not found"
}
$DNSInfo = $DNSResolve | ConvertTo-Json -WarningAction SilentlyContinue
# AD OU
$ADComputers = $null
$Domain = $ComputerName.Substring($ComputerName.IndexOf('.') + 1)
switch ($Domain) {
'nd.gov' {
try {
$ADComputers = Get-ADComputer -Identity $HostName -Properties * -ErrorAction SilentlyContinue
}
catch {
# empty because erroraction silentlycontinue doesn't work as expected
}
If ($ADComputers) {
$ADInfo = $ADComputers | ConvertTo-Json -WarningAction SilentlyContinue
}
Else {
$ADInfo = "AD object not found"
}
}
'Default' {
Write-Warning -Message "$ComputerName not nd.gov, review other domains manually"
}
}
# SCCM collections
$SCCMResult = Invoke-Command -ComputerName itdsccmp2.nd.gov -Credential $Credential -ArgumentList $Hostname -ScriptBlock {
Import-Module 'D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
Set-Location ITD:\
$CMDevice = Get-CMDevice -Name $args[0]
If ($CMDevice) {
Get-ITDCMDeviceMemberOf -ComputerName $args[0]
}
Else {
"SCCM object not found"
}
}
$SCCMInfo = $SCCMResult | ConvertTo-Json -WarningAction SilentlyContinue
Write-Verbose -Message "Updating SCTask with discovered information"
Update-ITDServiceNowRecord -ItemType "Catalog Task" -Number $SCTaskNum -Values @{work_notes = ("DNS Information: `n " + $DNSInfo) }
If ($vCenterInfo) {
}
If ($AzureInfo) {
}
Update-ITDServiceNowRecord -ItemType "Catalog Task" -Number $SCTaskNum -Values @{work_notes = ("Active Directory Information: `n " + $ADInfo) }
Update-ITDServiceNowRecord -ItemType "Catalog Task" -Number $SCTaskNum -Values @{work_notes = ("SCCM Information: `n " + $SCCMInfo) }
$CommentsForWorkNotes = $null
try {
$Notes = '<div><strong><span style="color: #c00000;">Decommissioned ' + (Get-Date -UFormat "%Y/%m/%d %H:%M:%S") + '</span></strong></div>'
Write-Verbose -Message "All records with Title matching $ComputerName were marked as decommissioned in the Notes field."
Update-ITDPassword -Title $ComputerName -AppendNotes -Notes $Notes -Credential $Credential -Force
$CommentsForWorkNotes += ("`nPasswordstate: All records with Title matching $ComputerName were marked as decommissioned in the Notes field. ")
}
catch {
}
# Power off VM
switch ($Ci.model_id.display_value) {
{ $_ -like "*VMware*" } {
$hardware_platform = "VMware";
$hardware_type = 'Virtual Machine'
$VMs = Get-VM -Name $FQDN -ErrorAction SilentlyContinue | Where-Object { $_.ExtensionData.summary.config.ManagedBy.Type -ne "placeholderVm" }
switch ( @($VMs).count ) {
{ 0 } {
Write-Warning "$FQDN not found in vCenter... is it Azure? Or does it not exist?"
}
{ $_ -gt 1 } {
Write-Verbose -Message "Multiple virtual machines with name $FQDN were found."
Write-Error -Message ("Multiple virtual machines with name $FQDN were found. Are there SRM placeholders? If so, unconfigure SRM and run this again. If there are no placeholders, confirm the virtual machine name.") -ErrorAction Stop
}
1 {
Write-Verbose -Message 'One virtual machine with name $FQDN were found.'
$TagAssignment = Get-TagAssignment -Entity $VMs
$vCenterInfo = $TagAssignment | select Tag, Entity | ConvertTo-Json -Depth 1
If ($VMs.PowerState -eq 'PoweredOn') {
Write-Verbose -Message "Power off VMware VM $FQDN"
$CommentsForWorkNotes += ("`nVMware: VM $FQDN has been powered off. ")
$VMs | Stop-VM -Confirm:$false
}
If ($vCenterInfo) {
# enter work_notes into sctask
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = ("vCenter Information: `n " + $vCenterInfo)
}
}
}
}
}
{ $_ -like "*Microsoft Virtual Machine*" } {
$hardware_platform = "Azure";
$hardware_type = 'Virtual Machine'
}
{ $_ -like "*HP*" } {
$hardware_platform = 'HPE';
$hardware_type = 'Physical'
}
default { $hardware_platform = 'Other' }
}
# SCCM removal
If ($SCCMResult -eq "SCCM object not found") {
# do nothing
}
Else {
Write-Verbose -Message "Attempt SCCM removal"
try {
$Domain = $ComputerName.Substring($ComputerName.IndexOf('.') + 1)
switch ($Domain) {
'nd.gov' { $SCCMDomain = 'NDGOV' }
'itd.nd.gov' { $SCCMDomain = 'NDGOV' }
'k12.nd.us' { $SCCMDomain = 'K12' }
'stg.k12.nd.us' { $SCCMDomain = 'K12STG' }
'ndcloud.gov' { $SCCMDomain = 'NDCLOUD'}
}
Write-Verbose -Message ("$Computername is SCCM Domain $SCCMDomain")
Invoke-Command -ComputerName itdsccmp2.nd.gov -Credential $Credential -ArgumentList $Hostname, $SCCMDomain -ScriptBlock {
Import-Module 'D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
Set-Location ITD:\
$Devices = Get-CMDevice -Name $args[0] | Where-Object Domain -EQ $args[1]
$Devices | select Name, Domain
ForEach ($Device in $Devices) {
If ($Device.Domain -match $SCCMDomain) {
Write-Verbose -Message ("SCCM: Removing " + $Device.Name + " on " + $Device.Domain + " domain")
$Device | Remove-CMDevice -Confirm:$false -Force
}
}
}
$CommentsForWorkNotes += ("`nSCCM: Device named $Hostname was removed. ")
}
catch {
}
}
# Active Directory removal
If ($ADInfo -eq "AD object not found") {
# do nothing
}
Else {
try {
switch ($Domain) {
'nd.gov' {
$ADComputers = Get-ADComputer -Identity $HostName
switch ( @($ADComputers).count ) {
{ 0 } { "AD: Not found" }
{ $_ -gt 1 } { "AD: More than one found" }
{ 1 } {
Write-Verbose -Message "AD: One found, removing"
$ADComputers
$ADComputers | Remove-ADObject -Recursive -Credential $Credential -Confirm:$false
}
}
$CommentsForWorkNotes += ("`nActive Directory: AD computer object with name $Hostname was removed from the nd.gov domain. ")
}
'Default' {
Write-Warning -Message "$ComputerName not nd.gov"
}
}
}
catch {
}
}
# DNS removal
If ($DNSResolve -eq "DNS object not found") {
# do nothing
}
Else {
try {
Write-Verbose "Attempting DNS removal"
Remove-ITDIbDnsRecord -ComputerName $ComputerName -Credential $RadiusCred
$CommentsForWorkNotes += ("`nInfoblox: DNS A Record was removed for $ComputerName. ")
}
catch {
}
}
# Solarwinds removal
try {
Remove-ITDSolarwindsNode -ComputerName $ComputerName -Credential $Credential
$CommentsForWorkNotes += ("`nSolarwinds: Node was removed for $ComputerName. ")
}
catch {
}
$CommentsForWorkNotes += ("`n `nWindows OS Decommission completed. $hardware_platform $hardware_type hardware is ready for removal. ")
$HardwareRemovalDescription = ("$ComputerName $hardware_platform $hardware_type hardware is ready for removal.")
Write-Verbose -Message "Add final comments for work notes into the SCTask, update the short_description for next workflow step"
Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
work_notes = $CommentsForWorkNotes;
short_description = $HardwareRemovalDescription;
}
}
end {
}
}