为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 C# 中获取 PSObject.Properties 的 ScriptProperty 值?

如何在 C# 中获取 PSObject.Properties 的 ScriptProperty 值?

C#
喵喵时光机 2022-12-24 11:47:04
我正在尝试使用“GET-PSDrive”命令通过 PowerShell 6.0 获取服务器的驱动器信息。直接在 PowerShell 中运行命令,我在输出表中看到“已用”和“免费”的值,但在代码中运行相同的命令虽然使用 Microsoft.Powershell.Sdk,但“已用”和“免费”字段不是可用的。我看到 PSObject.Properties 数组下列出的两个项目,但尝试访问我收到异常的值:“没有可用于在此线程中运行脚本的运行空间。您可以在 System.Management.Automation.Runspaces.Runspace 类型的 DefaultRunspace 属性中提供一个。您尝试调用的脚本块是:##”以下是我正在使用的 POC 代码:using (var psCon = PowerShell.Create()){     psCon.AddCommand("GET-PSDrive");     var psReturn = psCon.Invoke();     foreach (var psObj in psReturn)     {          var driveUsedValue = psObj.Properties["Used"].Value;     }}我期望获得该属性的值,但每次评估该值时,我都会收到一条错误消息,指出没有可用的运行空间。检查该属性,我确实看到它是一个 ScriptProperty,那么您如何获取生成的值呢?
查看完整描述

1 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

Used 属性称为 ScriptProperty。这意味着当它被调用时它会运行一个脚本。我们可以通过调用看到这一点:


get-PSDrive | get-member -Name Used

这返回


Name MemberType     Definition

---- ----------     ----------

Used ScriptProperty System.Object Used {get=## Ensure that this is a FileSystem drive...

我们可以深入挖掘并查看正在运行的脚本


get-PSDrive  | get-member -Name Used | select -ExpandProperty Definition

这将返回


System.Object Used {

    get=## Ensure that this is a FileSystem drive

    if($this.Provider.ImplementingType -eq [Microsoft.PowerShell.Commands.FileSystemProvider]){

        $driveRoot = ([System.IO.DirectoryInfo] $this.Root).Name.Replace('\','')

        $drive = Get-CimInstance Win32_LogicalDisk -Filter "DeviceId='$driveRoot'"

        $drive.Size - $drive.FreeSpace

    };

}

这就是您得到异常的原因There is no Runspace available to run scripts in this thread。这是因为该信息运行需要运行空间的脚本。


要解决此问题,您可以将所有属性转换为这样的注释属性


Get-PSDrive | %{

    $drive = $_

    $obj = new-object psobject

    $_.psobject.Properties.GetEnumerator() | %{

        $obj | Add-Member -MemberType NoteProperty -name $_.Name -Value $drive."$($_.name)" 

    }

    $obj

}

或者正如@mklement0 在评论中指出的那样


Get-PSDrive | Select-Object *

这是更好的解决方案。


它将返回一个 PSobjects 数组,其值作为注释而不是脚本


using (var psCon = PowerShell.Create()){

    psCon.AddScript(@"

        Get-PSDrive | Select-Object *

    ");



    var psReturn = psCon.Invoke();

    foreach (var psObj in psReturn)

    {

        var driveUsedValue = psObj.Properties["Used"].Value;

    }

}

*注意该值将只是使用的字节整数。


查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 112 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信