如何使用Microsoft Powershell设置Hyper-v虚拟机检查点的注解?

4uqofj5v  于 2023-01-13  发布在  Shell
关注(0)|答案(1)|浏览(201)

在Hyper-v中设置vm检查点的注解可以在GUI中很容易地实现。然后可以使用Powershell同样容易地检索这些注解。但是,我无法找到使用Powershell实际修改vm检查点注解的方法。
Set-VM cmdlet可以修改vm的注解,但它不接受Microsoft.HyperV.PowerShell.VMSnapshot的对象类型,因此排除了潜在的解决方案。

2ledvvac

2ledvvac1#

我没有看到使用Hyper-V cmdlet设置快照注解的方法。cmdlet实际上是基于WMI/CIM的,我们可以使用WMI/CIM API修改快照注解。
由于API使用起来不直观,我将代码 Package 在可重用的cmdlet中:

Function Set-VMSnapshotNotes {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)] [string] $VmName,
        [Parameter(Mandatory)] [string] $SnapshotName,
        [Parameter(Mandatory)] [string] $Notes
    )

    # Get VM
    $vm = Get-CimInstance -Namespace 'root\virtualization\v2' -Query "Select * From Msvm_ComputerSystem Where ElementName='$VmName'"

    if( -not $vm ) {
        $PSCmdlet.WriteError( [Management.Automation.ErrorRecord]::new( 
            [Exception]::new("Could not find VM '$VmName'"), 'VmNameNotFound', [Management.Automation.ErrorCategory]::ObjectNotFound, $VmName ))
        return
    }

    # Get VM snapshot settings
    $snapshot = $vm | Get-CimAssociatedInstance -ResultClassName Msvm_VirtualSystemSettingData -Association Msvm_SnapshotOfVirtualSystem |
        Where-Object ElementName -eq $SnapshotName

    if( -not $snapshot ) {
        $PSCmdlet.WriteError( [Management.Automation.ErrorRecord]::new( 
            [Exception]::new("Could not find snapshot '$SnapshotName' of VM '$VmName'"), 'SnapshotNameNotFound', [Management.Automation.ErrorCategory]::ObjectNotFound, $SnapshotName ))
        return
    }       

    # This doesn't modify the live snapshot settings, but only the local configuration data!
    $snapshot.Notes = $Notes

    # To be able to actually modify the live snapshot, configuration must be serialized.
    $serializer = [Microsoft.Management.Infrastructure.Serialization.CimSerializer]::Create()
    $snapshotBytes = $serializer.Serialize( $snapshot, [Microsoft.Management.Infrastructure.Serialization.InstanceSerializationOptions]::None )
    $snapshotStr   = [Text.Encoding]::Unicode.GetString( $snapshotBytes )

    # Now we can use method ModifySystemSettings of CIM class Msvm_VirtualSystemManagementService to actually modify the live snapshot settings.
    $service = Get-CimInstance -Namespace 'root\virtualization\v2' -class 'Msvm_VirtualSystemManagementService'
    $result = $service | Invoke-CimMethod -MethodName ModifySystemSettings -Arguments @{ SystemSettings = $snapshotStr }

    # If ReturnValue is 4096, the operation is performed asynchronously and $result.Job contains a CIM_ConcreteJob instance.
    # I'm not sure if this needs to be handled in case of setting only snapshot notes.
    if( $result.ReturnValue -notin 0, 4096 ) {
        $PSCmdlet.WriteError( [Management.Automation.ErrorRecord]::new( 
            [Exception]::new("Failed to set VM notes for snapshot '$SnapshotName' of VM '$VmName'"), 'ModifySystemSettingsFailed', [Management.Automation.ErrorCategory]::InvalidResult, $result.ReturnValue ))
        return
    }

    $result  # Output
}
    • 用法示例:**
$result = Set-VMSnapshotNotes -VmName 'TestVM' -SnapshotName 'Snapshot 1' -Notes "Foo Bar Baz $(Get-Date)"
"Result: $result"

$notes = Get-VMSnapshot -VMName 'TestVM' -Name 'Snapshot 1' | ForEach-Object Notes
"New notes: $notes"
    • 输出:**
Result: @{Job=; ReturnValue=0; PSComputerName=}
New notes: Foo Bar Baz 12/24/2022 14:27:19
    • 注:**
  • $result.ReturnValue等于4096时,操作异步完成。但在使用本地VM进行测试时,它始终为零。修改远程VM时可能会发生异步处理。请记住,设置可能不会立即更改。使用$result.Job示例时,可能需要等待异步操作完成。有关详细信息,请参阅ModifySystemSettings
  • 使用相同的原理,可以修改其他快照设置。请参见Msvm_VirtualSystemSettingData,了解理论上可以通过代码示例中的$snapshot变量修改的可用属性。尽管在GUI中大多数设置都是禁用的,因此这可能也无法通过编程方式工作。

相关问题