将脚本输出从一个巨大的 CSV 拆分为较小的 CSV

Breaking script output from one huge CSV to smaller CSVs

目前有一个脚本可以运行 遍历服务器上的所有用户文件并根据上次访问时间输出它们。客户想要一份关于去年未被触及的文件的报告。

问题是,报告太大了。我根据我的测试样本集估计超过 200 万行 CSV。因此,我不想使用一个 HUGE 文件,而是希望将此脚本转换为输出许多按用户细分的较小报告。

扫描根用户目录,吐出一个包含该用户名的 CSV,然后迭代到下一个用户,并重复。

$cutOffDate = (Get-Date).addYears(-1)
$arr = @()
$exclusions = @(".lnk",".url",".ini",".odc",".ctx",".upd",".ica")

gci "D:\USER_FILES\company\USERS\Lname, Fname" -Recurse | ? {
  $_.PSIsContainer -eq $False -and
  $_.LastAccessTime -le $cutOffDate -and
  $exclusions -notcontains $_.Extension -and
  $_.length -gt "0" -and
  $_.Directory -notmatch ".*USERS\.*\Personal\sysdata\cookies"
} | % {
  $obj = New-Object PSObject
  $obj | Add-Member NoteProperty Directory $_.DirectoryName
  $obj | Add-Member NoteProperty Name $_.Name
  $obj | Add-Member NoteProperty MB ("{0:N3}" -f ($_.Length/1MB))
  $obj | Add-Member NoteProperty created $_.creationtime
  $obj | Add-Member NoteProperty LastAccessed $_.LastAccessTime
  $obj | Add-Member NoteProperty LastMofified $_.LastWriteTime
  $obj | Add-Member NoteProperty Extension $_.Extension
  $arr += $obj
}

$arr | Export-CSV -notypeinformation "C:\Output.csv"

下面是编辑 - 输出到管道而不是数组

$cutOffDate = (Get-Date).addYears(-1)
$exclusions = @(".lnk",".url",".ini",".odc",".ctx",".upd",".ica")

Get-ChildItem 'D:\USER_FILES\company\USERS' | ? { $_.PSIsContainer } | % {
  $name = $_.Name
  Get-ChildItem $_.FullName -Recurse |
    ? {
      $exclusions -notcontains $_.Extension -and
      $_.PSIsContainer -eq $false -and
      $_.LastAccessTime -le $cutOffDate -and
      $_.length -gt "0" -and
      $_.Directory -notmatch '.*USERS\.*\Personal\sysdata\cookies'
    } |
    select DirectoryName, Name, @{n='MB';e={"{0:N3}" -f ($_.Length/1MB)}},
           CreationTime, LastAccessTime, LastWriteTime, Extension |
    Export-Csv "D:\User-Files-Output$name.csv" -NoType
}

注意:忽略初始路径,我目前是在diff环境下测试,所以C盘或者D盘,根路径还是USERS。

枚举用户文件夹(假设您的用户文件夹是 D:\USER_FILES\company\USERS 内名为 Lastname, Firstname 的文件夹),然后为每个用户递归到它们。另外,不要在循环中附加到数组。只需 select 您的属性并将输出通过管道传输到 Export-Csv。如果您有 PowerShell v3 或更新版本,您可以使用参数 -File-Directory 分别将 Get-ChildItem 的输出限制为文件或文件夹。

Get-ChildItem 'D:\USER_FILES\company\USERS' -Directory | % {
  $name = $_.Name
  Get-ChildItem $_.FullName -Recurse -File |
    ? {
      $_.LastAccessTime -le $cutOffDate -and
      $exclusions -notcontains $_.Extension -and
      $_.length -gt "0" -and
      $_.Directory -notmatch '.*USERS\.*\Personal\sysdata\cookies'
    } |
    select DirectoryName, Name, @{n='MB';e={"{0:N3}" -f ($_.Length/1MB)}},
           CreationTime, LastAccessTime, LastWriteTime, Extension |
    Export-Csv "C:$name.csv" -NoType
}

如果您仅限于使用 PowerShell v2,请将上面的内容更改为:

Get-ChildItem 'D:\USER_FILES\company\USERS' | ? { $_.PSIsContainer } | % {
  $name = $_.Name
  Get-ChildItem $_.FullName -Recurse |
    ? {
      -not $_.PSIsContainer -and
      $_.LastAccessTime -le $cutOffDate -and
      $exclusions -notcontains $_.Extension -and
      $_.length -gt "0" -and
      $_.Directory -notmatch '.*USERS\.*\Personal\sysdata\cookies'
    } |
    select DirectoryName, Name, @{n='MB';e={"{0:N3}" -f ($_.Length/1MB)}},
           CreationTime, LastAccessTime, LastWriteTime, Extension |
    Export-Csv "C:$name.csv" -NoType
}

移动你最后一行的逻辑:

 $arr | Export-CSV -notypeinformation "C:\Output.csv"

进入最终的ForEach-Object脚本块:

$obj | Export-Csv -NoTypeInformation -Path ("C:\{0}.csv" -f $user)

您需要从每个项目的路径中获取用户名,例如

$_.FullName -match 'D:\USER_FILES\company\USERS\([^\]+)\' | Out-Null
$user = $Matches[1]

因此,您的最终 ForEach-Object 脚本块如下所示:

$_.FullName -match 'D:\USER_FILES\company\USERS\([^\]+)\' | Out-Null
$user = $Matches[1]    
New-Object PSObject |
    Add-Member NoteProperty Directory $_.DirectoryName -PassThru |
    Add-Member NoteProperty Name $_.Name -PassThru |
    Add-Member NoteProperty MB ("{0:N3}" -f ($_.Length/1MB)) -PassThru |
    Add-Member NoteProperty created $_.creationtime -PassThru |
    Add-Member NoteProperty LastAccessed $_.LastAccessTime -PassThru |
    Add-Member NoteProperty LastMofified $_.LastWriteTime -PassThru |
    Add-Member NoteProperty Extension $_.Extension -PassThru |
    Export-Csv -NoTypeInformation -Path ('C:\{0}.csv' -f $user)