如何在C#中获取PSObject.Properties的ScriptProperty值? [英] How to get ScriptProperty Values of PSObject.Properties in C#?

查看:312
本文介绍了如何在C#中获取PSObject.Properties的ScriptProperty值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 GET-PSDrive命令通过PowerShell 6.0获取服务器的驱动器信息。直接在PowerShell中运行命令,我在输出表中看到 Used和 Free的值,但是使用Microsoft.Powershell.Sdk在代码中运行相同的命令,但 Used和 Free字段却没有

I am trying to get drive information for a server through PowerShell 6.0 using the 'GET-PSDrive' command. Running the command directly in PowerShell, I see the values for 'Used' and 'Free' within the output table, but running the same command in code though using the Microsoft.Powershell.Sdk the 'Used' and 'Free' fields are not available.

我看到PSObject.Properties数组下都列出了这两个项目,但是尝试访问该值时会收到异常:

I see both items listed under the PSObject.Properties array, but trying to access the value I receive the exception:

此线程中没有可用于运行脚本的运行空间。您可以在System.Management.Automation.Runspaces.Runspace类型的DefaultRunspace属性中提供一个。您尝试调用的脚本块是:##

"There is no Runspace available to run scripts in this thread. You can provide one in the DefaultRunspace property of the System.Management.Automation.Runspaces.Runspace type. The script block you attempted to invoke was: ##"

以下是我正在使用的POC代码:

The following is the POC code that I am working with:

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,那么如何获取该生成的值呢?

I am expecting to get the value of that property, but each time the value is evaluated I get an error saying that no runspace is available. Inspecting the property I do see that its a ScriptProperty, so how do you go about getting that generated value?

推荐答案

使用的属性被称为ScriptProperty。这意味着当它被调用时它将运行一个脚本。我们可以通过调用以下内容来查看:

The property Used is a called a ScriptProperty. It means when it is called it runs a script. We can see this by calling :

get-PSDrive | get-member -Name Used

此返回

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

我们可以更深入地研究并查看也在运行的脚本

We can dig deeper and see the script that is running also

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
    };
}

这就是为什么您会得到例外情况的原因没有可用于在此线程中运行脚本的运行空间。这是因为该信息运行的脚本需要一个运行空间。

This is why you get the exception There is no Runspace available to run scripts in this thread. It is because that info runs a script which needs a runspace.

要解决此问题,您可以将所有属性转换为此类便笺属性

to work around this you can turn all the properties into note properties like this

Get-PSDrive | %{
    $drive = $_
    $obj = new-object psobject
    $_.psobject.Properties.GetEnumerator() | %{
        $obj | Add-Member -MemberType NoteProperty -name $_.Name -Value $drive."$($_.name)" 
    }
    $obj
}

或@ mklement0在评论中指出

OR as @mklement0 pointed out in the comments

Get-PSDrive | Select-Object *

哪个是更好的解决方案。

Which is much better solution.

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

It will return an array of PSobjects with the values as notes instead of script

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;
    }
}

*请注意,该值将只是所使用字节的整数

*Note the value will just the integer of bytes used.

这篇关于如何在C#中获取PSObject.Properties的ScriptProperty值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆