如何在PowerShell中将数组对象转换为字符串对象?

时间:2016-01-15 13:34:46

标签: arrays string powershell certificate private-key

在尝试使用有关证书的信息创建CSV文件时,我有一个问题是将用户权限存储在私钥上。

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

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

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

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

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

enter image description here

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

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

1 个答案:

答案 0 :(得分:0)

正如评论中所述,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