将脚本输出从一个巨大的 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)
目前有一个脚本可以运行 遍历服务器上的所有用户文件并根据上次访问时间输出它们。客户想要一份关于去年未被触及的文件的报告。
问题是,报告太大了。我根据我的测试样本集估计超过 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)