# cron expression
# 47 8-16 * * 1-5

Param(
    [string]
    $SCTaskNum
)

New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred

$Filter = 'active=true^short_descriptionSTARTSWITHAutomated Server Build Task for Windows Machine'
$OpenTasks = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Filter $Filter | Sort-Object Number
If ($PSBoundParameters.ContainsKey("SCTaskNum")) {
    Write-Verbose -Message "SCTaskNum parameter found, value is $SCTaskNum" -Verbose
    $OpenTasks = $OpenTasks | Where-Object { $_.number.value -EQ $SCTaskNum }
}

$AllRitms = [System.Collections.ArrayList]@()

Write-Verbose -Message ("OpenTasks found: " + @($OpenTasks).Count) -Verbose

ForEach ($OpenTask in $OpenTasks) {
    $Ci = $null
    $BuildComplete = $null

    # get SCTask, Ritm
    $SCTaskNum = $OpenTask.number.value
    Write-Verbose -Message "Start $SCTasknum" -Verbose

    try {
        $SCTask = Get-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum
        $shortdescription = $SCTask.short_description.display_value
        $shortdescription_hostname = $shortdescription.split(' ')[7]
    
        If ($AllRitms | Where-Object sys_id -EQ $SCTask.request_item.value) {
            $Ritm = $AllRitms | Where-Object sys_id -EQ $SCTask.request_item.display_value
        }
        Else {
            $Ritm = Get-ITDServiceNowRecord -ItemType 'Request Item' -Number $SCTask.request_item.display_value -IncludeVariableSet
            $null = $AllRitms.Add($Ritm)
        }

        $ComputerName = ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).host_name
        $OperatingSystem = ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).operating_system

        switch ( ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).target_platform ) {
            'azure' { $target_platform = "Azure" }
            'vmware' { $target_platform = "VMware" }
        }

        $FormFQDN = ($Ritm.VariableSet | Where-Object host_name -EQ $shortdescription_hostname).host_name
        $FormHostName = $FormFQDN.split('.')[0]

        $Ci = Get-ITDServiceNowRecord -Table cmdb_ci -Filter ("name=" + $FormHostName)
        If ($Ci) {
            Write-Verbose -Message ("Ci found, sys_id = " + $Ci.sys_id + ", name = " + $Ci.name + ", fqdn = " + $Ci.fqdn) -Verbose
        }
        Else {
            # Ci does not exist
            Write-Verbose -Message ("Ci not found") -Verbose
        }
    
        switch ($Ci.model_id.display_value) {
            { $_ -like "*VMware*" } { $hardware_platform = "VMware"; $hardware_type = 'Virtual Machine' }
            { $_ -like "*Microsoft Virtual Machine*" } { $hardware_platform = "Azure"; $hardware_type = 'Virtual Machine' }
            { $_ -like "*HP*" } { $hardware_platform = 'HPE'; $hardware_type = 'Physical' }
            default { $hardware_platform = 'Other' }
        }

        Write-Verbose -Message "Confirm all agents are running"
        $ProcessList = @('ccmexec', 'cohesity*', 'nessus*', 'cortex*')
        switch ($target_platform) {
            'VMware' {
                $ProcessList += 'vmtoolsd'
            }
            'Azure' {
                Write-Verbose -Message "vmtoolsd not required for Azure VM"
            }
            Default {
                Write-Verbose -Message "no Ci means no platform check"
            }
        }
    }
    catch {
        Write-Error $error[0]
    }

    If ( $ComputerName -like "*.nd.gov" ) {
        try {
            $AgentCount = 0
            $svcitdpsuwin = Get-ITDPassword -UserName ndgov\svcitdpsuwin -Title ndgov\svcitdpsuwin
            $RunningProcess = Invoke-Command -Credential $svcitdpsuwin -ComputerName $FormFQDN -ArgumentList $ProcessList -ErrorAction Stop -ScriptBlock {
                Get-Process
            }
        
            If ($RunningProcess) {
                ForEach ($ProcessName in $ProcessList) {
                    If ($RunningProcess -match $ProcessName) {
                        Write-Verbose -Message "Process $ProcessName found." -Verbose
                        $AgentCount = $AgentCount + 1
                    }
                    Else {
                        Write-Warning -Message "Process $ProcessName not found"
                        # do not increase agentcount count
                    }
                }
            } 
        }
        catch [System.Management.Automation.Remoting.PSRemotingTransportException] {
            Write-Warning -Message "$FormFQDN unreachable via PSRemoting"
            $BuildComplete = $false
        }
    } Else {
        Write-Verbose -Message ($SCTaskNum + $ComputerName + " is not nd.gov, manual agent validation required.") -Verbose
    }

    <# if Task has been open for more than x hours, update description for humans to review
    $Hours = 6
    If ($SCTask.opened_at.value -lt (Get-Date).AddHours(-$Hours)) {
        $work_notes = ("New build Ci has not been found after $Hours hours, problem may have occurred.  Please review.`nPSU Job Id #" + $UAJob.Id)
        $shortdescription = "$target_platform $OperatingSystem VM Build for $ComputerName, NEED HUMAN REVIEW"            

        <#Update-ServiceNowRecord -ID $SCTask.number -Values @{
            work_notes       = $work_notes;
            shortdescription = $shortdescription;
        }
    }#>

    If ($AgentCount -ge @($ProcessList).count) {
        Write-Verbose "All required processes running, Windows is ready for use.  Update SCTask to notify physical/virtual hardware stakeholders." -Verbose
        $work_notes = ("$target_platform $hardware_type $FormFQDN Windows Guest OS complete.  `nPSU Job Id #" + $UAJob.Id)
        $shortdescription = "$target_platform $hardware_type $FormFQDN Windows Guest OS complete."            

        Write-Verbose -Message "Work notes: $work_notes" -Verbose
        Write-Verbose -Message "Short description: $shortdescription" -Verbose
        
        Update-ITDServiceNowRecord -ItemType 'Catalog Task' -Number $SCTaskNum -Values @{
            work_notes        = $work_notes;
            close_notes       = "$FQDN $target_platform Windows Guest OS complete.";
            short_description = $shortdescription;
            state             = 'Closed Complete'
        }
    }

    Write-Verbose -Message "End   $SCTasknum" -Verbose
}