【问题标题】:Not able to add data to csv file powershell无法将数据添加到 csv 文件 powershell
【发布时间】:2022-01-03 14:24:50
【问题描述】:

我正在尝试将数据添加到 csv 文件。

我首先创建带有标题的 csv,然后尝试添加行。但它返回空白 csv 文件


                $props=[ordered]@{
                 ServerName=''
                 SystemFolderPath=''
                 IdenityReference=''
                 FileSystemRights=''
                 
            }
            New-Object PsObject -Property $props | 
                 Export-Csv "C:\status_report.csv" -NoTypeInformation


$serverlist = Get-Content -Path "C:\ServerList.txt"

foreach($server in $serverlist)
{

                $paths_list = $env:Path -Split ';'
                
            Foreach ($sys_Path in $paths_list)
            {

                $Permissions = Get-Acl -Path $sys_Path
                $Users_Permissions = $Permissions.Access  | Where-Object {$_.IdentityReference}
                #$Users_Permission
                        Foreach  ($user in $Users_Permissions)
                        {
                                $IdenityReference = $user.IdentityReference.Value
                                $FileSystemRights = $user.FileSystemRights
                                
                                $NewLine = "{0},{1},{2},{3}" -f $server,$sys_Path,$IdenityReference,$FileSystemRights
                                $NewLine | Export-Csv -Path "C:\status_report.csv" -Append -NoTypeInformation -Force

                        }

            }
}

请让我知道我在这里做错了什么

【问题讨论】:

  • 我正在看这个,但我很好奇你是否尝试过 $NewLine 的写主机以确保它有东西要写?

标签: powershell csv


【解决方案1】:

您看到此问题的主要原因是,Export-Csv 期望通过管道传递 object 或 object[],而您传递的是格式化的 字符串。这是在 MS Docs 上指定的:

在将对象发送到Export-CSV cmdlet 之前不要对其进行格式化。如果Export-CSV 接收到格式化的对象,则 CSV 文件包含格式属性而不是对象属性。

PS /> 'server01,C:\Windows,Computer\User,FullControl' | ConvertTo-Csv
"Length"
"45"

除了附加到效率很低的 CSV 之外,除非有特殊需要,否则您要做的是先收集结果,然后将它们导出。

我不太清楚为什么需要| Where-Object { $_.IdentityReference },我把它留在那里但我认为不需要它。

关于$serverlist,如果您要在远程主机上运行它,您最好使用Invoke-Command,因为它允许并行调用。在这种情况下不需要外循环:

$serverlist = Get-Content -Path "C:\ServerList.txt"

# Collect results here
$result = Invoke-Command -ComputerName $serverlist -ScriptBlock {
    $paths_list = $env:Path -Split [System.IO.Path]::PathSeparator
    foreach($sys_Path in $paths_list)
    {
        $Permissions = (Get-Acl -Path $sys_Path).Access
        foreach($acl in $Permissions)
        {
            if(-not $acl.IdentityReference)
            {
                continue
            }   

            [pscustomobject]@{
                ComputerName     = $env:ComputerName
                SystemFolderPath = $sys_Path
                IdenityReference = $acl.IdentityReference.Value
                FileSystemRights = $acl.FileSystemRights
            }
        }
    }
} -HideComputerName

$result | Export-Csv -Path "C:\status_report.csv" -NoTypeInformation

【讨论】:

  • 谢谢@圣地亚哥
  • 知道了。赞赏。
  • 伟大的编辑! (+1)
  • @Theo 感谢 Theo,我看到你对 dcaz 回答的评论让我意识到我的错误。
  • @SantiagoSquarzon:我现在在远程服务器的脚本中收到此错误Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. + CategoryInfo : InvalidData: (:) [Get-Acl], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetAclCommand + PSComputerName
【解决方案2】:

接受上面的圣地亚哥,但这是我对你写的东西所做的。

$props = [ordered]@{
    ServerName       = ''
    SystemFolderPath = ''
    IdenityReference = ''
    FileSystemRights = ''
    
}
New-Object PsObject -Property $props | 
Export-Csv "C:\status_report.csv" -NoTypeInformation
$serverlist = Get-Content -Path "C:\ServerList.txt"
$result = $serverlist | ForEach-Object {

    foreach ($server in $_) {
        $paths_list = $null
        $paths_list = $env:Path -Split ';'
   
        Foreach ($sys_Path in $paths_list) {
            $Permissions = Get-Acl -Path $sys_Path
            $Users_Permissions = $Permissions.Access  | Where-Object { $_.IdentityReference }
            #$Users_Permission
            Foreach ($user in $Users_Permissions) {
                $IdenityReference = $null
                $FileSystemRights = $null
                $IdenityReference = $user.IdentityReference.Value
                $FileSystemRights = $user.FileSystemRights
                   
                [PSCustomObject]@{
                    Server     = $server
                    Sys_Path   = $sys_Path
                    Referecent = $IdenityReference
                    Rights     = $FileSystemRights
                }
                $sys_Path = $null
            }
        }
    }
}
$result | Export-Csv -Path "C:\status_report.csv" -NoTypeInformation

【讨论】:

  • $serverlist = Get-Content -Path "C:\ServerList.txt" 上面的所有内容都是多余的,但主要是:这只是从调用者本地机器收集信息,与远程服务器上的内容无关..
【解决方案3】:

Santiago 的回答是正确的,并且包含了您在这里了解问题所需的所有信息。

我只是想为您提供在脚本中要做的最少修改:

  • 将 $props 自定义对象替换为函数(即 CreateCustomObject)

     function CreateCustomObject($val1, $val2, $val3, $val4) {
         $NewObject = New-Object PSObject ;
         Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "ServerName" -Value $val1 ;
         Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "SystemFolderPath" -Value $val2  ;
         Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "IdenityReference" -Value $val3  ;
         Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "FileSystemRights" -Value $val4  ;
         return $NewObject ;
    
     }
    
  • 用数组替换字符串变量 $NewLine

     $NewLine = @()
     $NewLine += CreateCustomObject $server $sys_Path $IdenityReference $FileSystemRights
    
  • 仅在收集数据后写入 CSV(将命令移至脚本末尾)

所以最终的脚本看起来像这样:

    function CreateCustomObject($val1, $val2, $val3, $val4) {
        $NewObject = New-Object PSObject ;
        Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "ServerName" -Value $val1 ;
        Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "SystemFolderPath" -Value $val2  ;
        Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "IdenityReference" -Value $val3  ;
        Add-Member -InputObject $NewObject -MemberType NoteProperty -Name "FileSystemRights" -Value $val4  ;
        return $NewObject ;

    }
    
    $serverlist = Get-Content -Path "C:\Temp\ServerList.txt"
    $NewLine = @()

    foreach($server in $serverlist) {

        $paths_list = $env:Path -Split ';'
            
        Foreach ($sys_Path in $paths_list) {
            $Permissions = Get-Acl -Path $sys_Path
            $Users_Permissions = $Permissions.Access  | Where-Object {$_.IdentityReference}
            #$Users_Permission
            Foreach  ($user in $Users_Permissions) {
                $IdenityReference = $user.IdentityReference.Value
                $FileSystemRights = $user.FileSystemRights
                $NewLine += CreateCustomObject $server $sys_Path $IdenityReference $FileSystemRights
            }

        }
    }

    $NewLine | Export-Csv -Path "C:\temp\status_report.csv" -NoTypeInformation -Force

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 2012-04-06
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    相关资源
    最近更新 更多