[CmdletBinding()] param ( [int] $Id ) Write-Verbose -Message "Connect to vCenter" -Verbose Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -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" } } # get list of All vCenter Scheduled Tasks $si = Get-View ServiceInstance $scheduledTaskManager = Get-View $Si.Content.ScheduledTaskManager Write-Verbose -Message ("Gathering all scheduled tasks with AutoSnap in the task name, this will take some time") $AllScheduledTasks = Get-View -Id $scheduledTaskManager.ScheduledTask | Where-Object { $_.Info.Name -like "AutoSnap*" } Write-Verbose -Message "Get SQL records with status of Scheduled" -Verbose # get list of Scheduled from database $SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Scheduled'" $SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose switch ($PSBoundParameters.Keys) { Id { Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id" } } Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Scheduled status") -Verbose Write-Verbose -Message "Start Scheduled > Taken Loops" ForEach ($SqlRecord in @($SqlRecords) ) { $Snapshot = $null Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose $Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue If ($Snapshot) { Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose Write-Verbose -Message ("Setting SQL status to Taken") -Verbose # if status has changed from requested to taken, update database status field $TakenDateTimeSql = ($Snapshot.Description | ConvertFrom-Json).Taken.ToString('yyyy/MM/dd HH:mm:ss') $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Taken', TakenDateTime = '" + $TakenDateTimeSql + "' WHERE ID = " + $Snapshot.Name.split('_')[1]) Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose } Else { Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose If ($SqlRecord.DateTime -lt (Get-Date)) { Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " not found, and its requested datetime has passed") -Verbose # Update SQL record to status Failed-ScheduledNotTaken $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-ScheduledNotTaken' WHERE ID = " + $SqlRecord.Id) Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose } } Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose } Write-Verbose -Message "End Scheduled > Taken Loops" $SqlRecord = $null $SqlRecords = $null $SqlQueryUpdate = $null # get list of taken from database Write-Verbose -Message "Start Taken > Expire Loops" Write-Verbose -Message "Get SQL records with status of Taken" -Verbose $SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Taken'" $SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose switch ($PSBoundParameters.Keys) { Id { Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id" } } # check status of all Taken SQLRecords Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Taken status") -Verbose ForEach ($SqlRecord in @($SqlRecords) ) { $Snapshot = $null Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose $Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue If ($Snapshot) { Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose # if expired datetime is in the past, set status to expired If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) { Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has expired.") -Verbose $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1]) Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose } } Else { Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id) Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose } Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose $SqlRecord = $null $SqlRecords = $null $SqlQueryUpdate = $null } # get list of Expired from SQL database Write-Verbose -Message "Start Expired > Removed Loops" Write-Verbose -Message "Get SQL records with status of Expired" -Verbose $SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Expired'" $SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose switch ($PSBoundParameters.Keys) { Id { Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id" } } # check status of all Expired SQLRecords Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Expired status") -Verbose ForEach ($SqlRecord in @($SqlRecords) ) { $Snapshot = $null Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose $Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue If ($Snapshot) { Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found. Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ". Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose # if expired datetime is in the past, set status to expired If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) { Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " is expired. Will be removed at next Removal run") -Verbose #$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1]) #Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose } } Else { Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id) Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose } Write-Verbose -Message ("End AutoSnap_" + $SqlRecord.Id) -Verbose $SqlRecord = $null $SqlRecords = $null $SqlQueryUpdate = $null } # get list of requested from SQL database Write-Verbose -Message "Start Requested > Scheduled Loops" Write-Verbose -Message "Get SQL records with status of Requested" -Verbose $SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Requested'" $SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose switch ($PSBoundParameters.Keys) { Id { Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id" } } # check status of all Requested SQLRecords Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Requested status") -Verbose ForEach ($SqlRecord in @($SqlRecords) ) { # does the scheduled tasks exist? If ($AllScheduledTasks | Where-Object { $_.Info.Name -eq ("AutoSnap_" + $SqlRecord.Id + '_' + $SqlRecord.VMName) }) { # yes - update SQL status to Scheduled Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " vCenter scheduled task exists.") -Verbose 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 } Else { # no # has date/time passed? (10 minute buffer) If ($SqlRecord.DateTime -lt (Get-Date).AddMinutes(-10)) { # yes - set SQL status to Failed-RequestedNotScheduled Write-Warning -Message ("AutoSnap_" + $SqlRecord.Id + " was not scheduled before its datetime.") $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-RequestedNotScheduled' WHERE ID = " + $SqlRecord.ID) Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose } Else { # no ??? } Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " scheduled task does not exist.") } } Write-Verbose -Message "End Requested > Scheduled Loops" $SqlRecord = $null $SqlRecords = $null $SqlQueryUpdate = $null Disconnect-ITDvCenter