<#
.SYNOPSIS
    Creates a vCenter scheduled task that will create a virtual machine snapshot.
.DESCRIPTION
    Creates a vCenter scheduled task that will create a virtual machine snapshot.
.NOTES
    
.LINK
    https://northdakota.service-now.com/nav_to.do?uri=kb_knowledge.do?sysparm_query=number=KB0017146
#>

[CmdletBinding()]
param (
    [Parameter(
        Mandatory = $true,
        HelpMessage = "The VMware virtual machine name.  This is most commonly the FQDN.  You can verify the virtual machine name by logging into vCenter.  Multiple entries can be submitted if the field loses focus, and you go back to it.  For example, after each entry hit Tab, then Shift-Tab back."
    )]
    [string[]]
    $VMName,

    [Parameter(Mandatory = $true,
        HelpMessage = "The DateTime you want the snapshot to occur.")]
    [datetime]
    $DateTime = (Get-Date),

    [Parameter(Mandatory = $true,
        HelpMessage = "How many hours the snapshot will exist.  The snapshot will be automatically deleted after the duration.  Maximum value is 72 hours.")]
    [ValidateRange(1, 72)]
    [int]
    $DurationHours = 4,

    [Parameter(HelpMessage = "Email address that you want vCenter to notify when the snapshot is taken.  Multiple entries can be submitted if the field loses focus, and you go back to it.  For example, after each entry hit Tab, then Shift-Tab back.")]
    [string[]]
    $Email
)

Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id

$StartDateTime = $DateTime
$EndDateTime = $StartDateTime.AddHours($DurationHours)
Write-Verbose -Message ("UAJob.ComputerName = " + $UAJob.ComputerName) -Verbose
switch($UAJob.ComputerName){
    "ITDWINAUTOT1" {
        $ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
        $Database = "ITD-Systems-Automation"
        $SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
    }
    "ITDWINAUTOP1" {
        $ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
        $Database = "ITD-Systems-Automation"
        $SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
    }
}

$StartDateTimeSql = $StartDateTime.ToString('yyyy/MM/dd HH:mm:ss')
$EndDateTimeSql = $EndDateTime.ToString('yyyy/MM/dd HH:mm:ss')

Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr
Write-Verbose -Message "After Connect vCenter" -Verbose


ForEach ($name in $VMName) {
    Write-Verbose -Message ("Add record to SQL") -Verbose
    $SqlQuery = "INSERT INTO [$SnapshotTable] (VMName, DateTime, RequestedBy, DurationHours,Status,ExpireDateTime,NotifyEmail,PSUJobIdRequest) Values ('$Name', '$StartDateTimeSql', '$RequestedBy', $DurationHours, 'Requested', '$EndDateTimeSql','$Email','$PSUJobId');SELECT SCOPE_IDENTITY();"
    Write-Verbose -Message $SqlQuery -Verbose
    $SnapshotId = (Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose).Column1
    Write-Verbose -Message ("Snapshot ID is $SnapshotId") -Verbose

    Write-Verbose -Message "Get SQL record" -Verbose
    $SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE ID='$SnapshotId'"
    Write-Verbose -Message $SqlQuery -Verbose
    $SqlRecord = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose
    Write-Verbose -Message $SqlRecord -Verbose

    Write-Verbose -Message ("Determine description metadata") -Verbose
    $MetadataObj = @{
        Id              = [int]$SnapshotId;
        Taken           = $StartDateTime;
        Expire          = $EndDateTime;
        RequestedBy     = $RequestedBy;
        DurationHours   = $DurationHours;
        PSUJobIdRequest = $PSUJobId;
    }

    Write-Verbose -Message ("Create VM Scheduled Task for Snapshot " + $SnapshotId) -Verbose

    $NewITDVMwareVMSnapshotTaskParams = @{
        VMName      = $name;
        Name        = ("AutoSnap_" + $SnapshotId)
        Description = $MetadataObj | ConvertTo-Json
        DateTime    = $StartDateTime;
    }
    
    switch ($PSBoundParameters.Keys) {
        Email {
            $NewITDVMwareVMSnapshotTaskParams.Email = $Email
        }
    }
    
    try {
        New-ITDVMwareVMSnapshotTaskV3 @NewITDVMwareVMSnapshotTaskParams -Verbose -ErrorAction Stop
        Write-Verbose -Message ("Setting SQL status to Scheduled") -Verbose
        $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Scheduled' WHERE ID = " + $SqlRecord.ID)
        Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
    
        Write-Verbose -Message ($NewITDVMwareVMSnapshotTaskParams.Name + " has been scheduled.") -Verbose
    }
    catch {
        Write-Verbose -Message "ObjectNotFound Error" -Verbose
        switch ($Error[0].Exception.ErrorCategory) {
            'ObjectNotFound' {
                # update SQL with error  
                Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed, ObjectNotFound.") -Verbose
                $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-VMNotFound' WHERE ID = " + $SqlRecord.ID)
                Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
            }
            'Default' {
                # update SQL with error  
                Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has failed.") -Verbose
                $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-GenericError' WHERE ID = " + $SqlRecord.ID)
                Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
            }
        }
        Write-Error -Message $Error[0]
    }
}

Disconnect-ITDvCenter

# Write-Verbose -Message ("If scheduled task is created successfully, create SNow CHG for this, using scheduled StartDateTime... work TBD") -Verbose
