【问题标题】:How do I convert an array object to a string object in PowerShell?如何在 PowerShell 中将数组对象转换为字符串对象?
【发布时间】:2016-01-15 13:34:45
【问题描述】:

在尝试创建包含证书信息的 CSV 文件时,我在将用户权限存储在私钥上时遇到了问题。

问题是我想在一个属性中存储多个值,所以我使用了一个数组。 起初我没有错误,但是即使在数组有值的情况下,我的 csv 文件中的列仍然为空。

使用简单的 Write-Host,我可以看到我的数组具有预期值,因此这部分工作正常。

为了进一步调查,我添加了以下行:

Get-Member $certs.GetValue("UserRights")

这给出了一个错误,表明我必须将我的变量转换为字符串变量。

所以接下来我尝试将此数组转换为单个字符串。 我尝试了几种方法,但我的错误并没有消失,所以它不起作用。 下面是我的完整代码,其中包含一些以前的尝试。

cls $certs = Get-ChildItem cert:\LocalMachine -Recurse  | Where-Object {-not $_.PSIsContainer} | Select * Write-Host ("There were {0} certificates" -f ($certs | Measure-Object).Count)

foreach($certificate in $certs) {
    if($certificate.HasPrivateKey)
    {
        Write-Host "Certificate's PSChildName is" $certificate.PSChildName
        $rsaFile = $certificate.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
        $fullPath = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\" + $rsaFile
        $acl = Get-Acl -Path $fullPath
        foreach($accessrule in $acl.Access)
        {
            Write-Host "User" $accessrule.IdentityReference "has the following rights:" $accessrule.FileSystemRights
        }

        Write-Host "------"

        $UserRechten = @()

         foreach($accessrule in $acl.Access)
        {
         $UserRechten += "{0}:{1};" -f ($accessrule.IdentityReference,$accessrule.FileSystemRights)
        }  



        Write-Host "================================================================"


        # -join $UserRechten
        # $Userrechten | out-string
        # $UserRechten = [system.String]::Join(" ", $UserRechten)
        $separator = ";"
        [string]::Join($separator,$UserRechten)

        $certs | Add-Member -MemberType NoteProperty -Name "UserRights" -Value $UserRechten -Force

        Write-Host "UserRechten has value : "$UserRechten

        Get-Member $certs.GetValue("UserRights")

        Write-Host "================================================================"


    } } 


$Certs | Add-Member -MemberType NoteProperty -Name "MachineName" -Value $env:COMPUTERNAME -Force
# $certs | Add-Member -MemberType NoteProperty -Name "Store" -Value 'My' -Force $RunDate = Get-Date -Format 'yyyy-MM-dd' $certs | Add-Member -MemberType NoteProperty -Name "RunDate" -Value $RunDate -Force $certs | Add-Member -MemberType NoteProperty -Name "Owner" -Value $env:USERNAME -Force

$Certs | Select * | Export-Csv c:\Certificaten\LocalCertsAll_$env:COMPUTERNAME.csv 
$Certs | Select MachineName, Owner, PSParentPath, DnsNameList, PSChildName, NotBefore, NotAfter, Rundate, EnhancedKeyUsageList, HasPrivateKey, SerialNumber, Issuer, Subject, FriendlyName, UserRigthts | 
    Export-CSV c:\Certificaten\Localcerts_$env:COMPUTERNAME.csv

【问题讨论】:

  • GetValue 是一个索引访问器,$certs.GetValue(0)$certs[0] 相同。你想用Get-Member $certs.GetValue('UserRights') 完成什么?
  • 也许只尝试'Get-Member $certs.UserRights'
  • 如果您只想将用户权限、私钥容器或整个证书的数据成员保存在 CSV 文件中,那么您肯定不想要get-membergm 提供有关参数类型的信息,如果您已经知道要保存的内容,则不需要这些信息。目前尚不清楚是什么失败了。您能否更新您发布并提供信息,尤其是错误消息?最后,如果您将 $UserRechten 初始化为空字符串,那么您的 foreach 循环将提供用户权限的串联字符串,您将不需要 -join 代码。

标签: arrays string powershell certificate private-key


【解决方案1】:

如 cmets 中所述,Get-Member 可能不是您要查找的内容

您(几乎可以肯定)不想将UserRights 成员属性添加到$Certs 数组,而是添加到$Certs 中的各个对象。

(为了便于阅读,我删除了一堆多余的 Write-Host 语句):

$CertsAmended = foreach($Certificate in $certs)
{
    if($certificate.HasPrivateKey)
    {
        $rsaFile = $certificate.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
        $fullPath = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\" + $rsaFile
        $acl = Get-Acl -Path $fullPath

        # Create the UserRights value using -join
        $UserRechten = @(foreach($accessrule in $acl.Access){
            Write-Host "User" $accessrule.IdentityReference "has the following rights:" $accessrule.FileSystemRights
            "{0}:{1}" -f ($accessrule.IdentityReference,$accessrule.FileSystemRights)
        }) -join ";"

        # Add the property to the individual object
        $Certificate | Add-Member -MemberType NoteProperty -Name "UserRights" -Value $UserRechten

        Write-Host "Userrights: " $UserRechten

        # "Drop" the certificate object (now with a UserRights value) back onto the pipeline
        $Certificate
    } 
} 

现在您可以根据需要将$CertsAmended 数组导出为 CSV


如果您觉得$var = @(foreach($item in $collection){}) -join ';' 不好看,请将其分成两个陈述:

$UserRechten = foreach($accessrule in $acl.Access)
{
    # Create UserRight string here, without ;
}
$UserRechten = $UserRechten -join ';'

对于$fullPath 变量,您可能需要使用Join-Path cmdlet:

$fullPath = Join-Path "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\" $rsaFile

【讨论】:

  • 谢谢,这行得通。唯一奇怪的是命令 Get-Member $certs.UserRights 没有给出任何结果。:在此对象上找不到属性“UserRights”。确保它存在。
  • 因为它没有。它作为属性存在于 inside $certs 的每个对象上,但不存在于 $certs 本身上。试试$certs | Get-Member -Name UserRights
猜你喜欢
  • 2022-10-07
  • 1970-01-01
  • 2020-07-15
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
相关资源
最近更新 更多