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