如何仅使用 CIM cmdlet(而非 WMI cmdlet)在 Powershell 中创建 VSS 卷影副本?

How to create a VSS shadow copy in Powershell using only CIM cmdlets (not WMI cmdlets)?

这里是 Powershell 新手,所以如果以下问题很愚蠢,请多多包涵...

我想在 Powershell 中创建一个 VSS 快照,并且找到了许多使用 WMI 函数来执行此操作的示例。常见模式有

# Pattern 1
$class=[WMICLASS]"root\cimv2:win32_shadowcopy"
$class.create("C:\", "ClientAccessible")

# Pattern 2
(gwmi -List Win32_ShadowCopy).Create("C:\", "ClientAccessible")

我看到的所有代码都使用了 Powershell 的 WMI cmdlet。 但是,根据大量参考资料 (e.g. here),我的印象是我们不应该再使用 WMI cmdlet。

所以我试图了解如何仅使用 CIM cmdlet 创建 VSS 快照,但没有成功。第一个想法是创建一个新的 Win32_ShadowCopy 实例,根据需要设置其属性并在其上调用 Create 方法。这在第一步中失败了:

PS C:\Users\Administrator> New-CimInstance Win32_ShadowCopy
New-CimInstance : Not supported 
At line:1 char:1
+ New-CimInstance Win32_ShadowCopy
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotImplemented: (Win32_ShadowCopy:CimInstance) [New-CimInstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x8004100c,Microsoft.Management.Infrastructure.CimCmdlets.NewCimInstanceCommand

显然 New-CimInstance 没有为 Win32_ShadowCopy 实现。

在进一步的研究中,还发现(与 WMI cmdlet 相比)CIM cmdlet 不 return 可以调用 Create 方法的对象(我已经删除了以下代码中输出的一些空行):

PS C:\Users\Administrator> get-cimclass -Class Win32_ShadowCopy

   NameSpace: ROOT/cimv2

CimClassName                        CimClassMethods      CimClassProperties                                                 
------------                        ---------------      ------------------                                                 
Win32_ShadowCopy                    {Create, Revert}     {Caption, Description, InstallDate, Name...}                       

PS C:\Users\Administrator> get-wmiobject -List Win32_ShadowCopy

   NameSpace: ROOT\cimv2

Name                                Methods              Properties                                                         
----                                -------              ----------                                                         
Win32_ShadowCopy                    {Create, Revert}     {Caption, ClientAccessible, Count, Description...}                 

根据我的理解,上面的内容表明由 get-cimclassget-wmiobject 编辑的对象 return 都应该公开相​​同的方法。但是,当我们尝试调用 Create 方法时:

PS C:\Users\Administrator> $(get-wmiobject -List win32_shadowcopy).Create("C:\", "ClientAccessible")

__GENUS          : 2
__CLASS          : __PARAMETERS
__SUPERCLASS     : 
__DYNASTY        : __PARAMETERS
__RELPATH        : 
__PROPERTY_COUNT : 2
__DERIVATION     : {}
__SERVER         : 
__NAMESPACE      : 
__PATH           : 
ReturnValue      : 0
ShadowID         : {8918619B-BE7F-4FE2-9B9C-C6B3B71CC749}
PSComputerName   : 

PS C:\Users\Administrator> $(get-cimclass -Class Win32_ShadowCopy).Create("C:\", "ClientAccessible")
Method invocation failed because [Microsoft.Management.Infrastructure.CimClass] does not contain a method named 'Create'.
At line:1 char:3
+ $(get-cimclass -Class Win32_ShadowCopy).Create("C:\", "ClientAccessib ...
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

显然,我不能使用 get-cimclass 创建卷影副本。 get-ciminstance也是如此;如果至少有一个快照已经存在,后者将失败并显示与 get-cimclass 相同的错误消息,否则会抛出另一个错误,因为 returned 对象为空。

那么我需要做什么才能仅使用 CIM cmdlet 创建卷影副本?

我刚开始玩这个,但这个命令似乎有效:

Invoke-CimMethod -MethodName Create -ClassName Win32_ShadowCopy -Arguments @{ Volume= "C:\" }

正如您所注意到的,您不能直接在实例上调用 CIM 方法。由于 Cim cmdlet 通过远程处理工作,因此实例不活动(有人说脱水)并且方法被删除。因此,“不包含名为...的方法”Invoke-CimMethod 旨在解决这个问题。

我确实发现发现有时会很棘手,但它是可行的。例如,我以前从未使用过此 class,但很容易找到可能的调用示例,例如:

(Get-CimClass Win32_ShadowCopy).CimClassMethods

Name   ReturnType Parameters                  Qualifiers
----   ---------- ----------                  ----------
Create     UInt32 {Context, Volume, ShadowID} {constructor, implemented, static}
Revert     UInt32 {ForceDismount}             {implemented}

我在一分钟内完成了所有...

注意:您是正确的 Get-WMIObject 等类似内容已弃用并已从 PowerShell 7+ 中删除。最好继续使用 Cim cmdlet,并在它们出现时完成这些调整...

Introduction to CIM Cmdlets

Scripting Guys CIM Vs WMI