【问题标题】:How to write information to .csv file via streamwriter如何通过 streamwriter 将信息写入 .csv 文件
【发布时间】:2020-01-08 13:15:54
【问题描述】:

我正在尝试使用 powershell 脚本将大量信息写入 .csv 文件。我正在通过 SCCM 配置管理器中的“运行脚本”功能在 1500 台计算机上运行此脚本。该脚本在所有机器上运行,但并非所有机器在文件中都有关于它们的信息。在 1352 台机器中,只有 375 台被写入文件。我怀疑程序运行速度太快而无法在下一台机器运行脚本之前打开和关闭文件,并且无法写入文件,因为它仍然处于打开状态。有什么想法可以解决这个问题吗?我看过有关使用 StreamWriter 的帖子,但不确定是否能解决我的问题。

我尝试将计算机分成更小的组,例如一次 8 台,但 8 台中只有 5 台将信息写入文件。代码如下,它可以工作。

#Overrides GPO execution policy
Set-ExecutionPolicy Bypass


#Gets and writes computer name to .csv file
$env:COMPUTERNAME = HostName

#Checks the path to see if a particular file is present
$DeplPath = "AppData\LocalLow\Sun\Java\Deployment\deployment.properties"


#Checks each user profile on machine for the deployment.properties file and writes to .csv "True" if present and "False" if it isn't
$javausers = foreach ($User in Get-ChildItem C:\Users -Directory){
    $folder = Join-Path $User.FullName $DeplPath
    if (Test-Path $folder) {
        $TestResult = "True  - deployment.properties"
    } Else {
        $TestResult = "False - Path not found"
    }
    [PSCustomObject]@{
        "Computer Name" = $env:COMPUTERNAME 
        "Java User True/False"       = $TestResult
        "Users"         = $user.Name
        #"Last Write Time" = $file.LastWriteTime = (Get-Date)

    }
}

#This is used for on-screen display only
#$javausers

#Tests path accessibility and writes an error file to the local machine if the path can't be found
try
{
$javausers | Export-Csv -NoTypeInformation -Path "\\anyserver\Java_User_Reports\testjava.csv" -Append

}
catch
{
$_| Out-File "c:\Temp\java_error.txt"

}

我希望将脚本正在搜索的有关每个用户的信息写入 1500 台机器中的每台机器的文件中。

【问题讨论】:

  • 这可能很愚蠢,但我可能会让每个系统都编写自己的文件。然后要么读取所有 1500 个文件,要么稍后合并数据。如果您不使用Export-Csv,您可能有更多选择,但不使用它会失去其他好处。
  • @AdminOfThings 这是一个考虑因素。我希望有其他选择。
  • 如何写入文件并不重要。您必须打开它进行写入,这意味着锁定文件以进行写入,这会产生竞争条件。 Export-Csv 和 StreamWriter 都必须这样做,并且文件共享因保留锁的时间超过远程应用程序需要它们而臭名昭著。你仍然会有潜在的竞争条件。如果这是一个 Windows 登录脚本,那么您还必须担心脚本在网络可用之前运行,这也可能导致此类问题。
  • (Csv) 文件根本不适合同时从不同帐户写入,您需要一个支持record locking 的数据库。说您可能为此使用 Active Directory(如果已安装),它实际上本身就是一个数据库,并使用一个或多个(未使用或特殊)用户属性作为您的信息。无论如何,我同意@Bacon Bits,你的下一个障碍将是the Windows Fast Logon Optimization feature
  • 感谢大家的意见。我只是决定在最后添加一个时间戳,以便每次为每台机器创建一个新文件,然后按照@AdminOfThings 的建议将数据合并到一个文件中。这适用于我正在做的事情。

标签: windows powershell streamwriter


【解决方案1】:

我能够找到一个更简单的解决方案,只需在文件名中添加一个 Get-Date 选项,这样 if 也会拉出毫秒,确保每次都创建一个新文件,而不是之前的文件覆盖。这在几分钟内创建了 1365 个文件。我将输出行更改为以下:

$dateTime | Export-Csv -NoTypeInformation -Path "\\anyserver\Java_User_Reports\$env:COMPUTERNAME-javausers-$(Get-Date -Format "yyyyMMddHHmmssff").csv" -Append

然后我将文件复制到我机器上的本地文件夹,打开命令提示符,输入命令以更改文件所在的目录路径。然后我输入命令来查看文件夹中的文件并确保我想要的所有文件都在那里。最后,我输入了 copy *.csv newfilenamehere.csv,以便将所有信息放在一个文件中。结果正是我所需要的,并解决了从多台计算机获取信息的问题,而无需脚本保持文件打开且不允许将其他信息写入其中。

【讨论】:

    猜你喜欢
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2016-08-03
    • 2020-05-23
    • 1970-01-01
    • 2016-05-03
    相关资源
    最近更新 更多