<#
.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 {
        
    }
}