在继续使用新Csv之前,是否可以为导出Csv指定要写入的最大行数?(拆分文件)
此脚本审核共享并创建一个CSV,详细说明找到的文件名及其文件扩展名信息-这很好。问题是CSV的行数往往超过Excel所能打开的行数。有没有一种方法可以分割文件?比如说在x行数之后创建一个新的CSV文件在继续使用新Csv之前,是否可以为导出Csv指定要写入的最大行数?(拆分文件),csv,powershell,Csv,Powershell,此脚本审核共享并创建一个CSV,详细说明找到的文件名及其文件扩展名信息-这很好。问题是CSV的行数往往超过Excel所能打开的行数。有没有一种方法可以分割文件?比如说在x行数之后创建一个新的CSV文件 # changes PowerShell prompt to the directory the script is being executed from function Get-ScriptDirectory { $Invocation = (Get-Variable MyInvo
# changes PowerShell prompt to the directory the script is being executed from
function Get-ScriptDirectory {
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}
$ISEScriptPath = Split-Path -Parent $psISE.CurrentFile.Fullpath -EA SilentlyContinue
if ($ISEScriptPath -eq $null) {
cd $(Get-ScriptDirectory -EA SilentlyContinue)
} else {
cd $ISEScriptPath
}
# checks for logs directory - if directory does not exist creates it
$Logs = Test-Path "$PWD\Logs"
if (-not $Logs) {
md "$PWD\Logs"
}
############# Main Script ################
$servers = Get-content .\servers.txt # servers.txt should be in script location containing list of servers to be audited
$share = "e$" # change this to audit location
foreach ($server in $servers) {
$now = get-date -format _HHmm_dd-MM-yyyy
# User Config
$report = ("FileExtAudit_"+ $server + "_" + $share + "$now.csv") # Name of the file to write out to.
$scanFrom = "\\$server\$share" # Script will audit this location and everything below (if it has permissions..)
gci $scanFrom -recurse | ? {$_.PSIsContainer -eq $False} |
Select-Object DirectoryName, Name, Extension, Length, LastAccessTime,
@{l="HSM";e={if( $_.Attributes -match "Compressed"){"True"} else {"False"} }},
@{l="ACL";e={[string]((Get-Acl $_.FullName).Owner)}} |
Export-Csv "$PWD\Logs\$report" -NoTypeInformation
}
您可以将结果保存到变量中,并使用
.Count
方法对其进行迭代,然后自己拆分。(select-first X
或select-index 1000..1999
等)导出Csv
不支持将输入拆分为多个文件。您必须自己实现逻辑
$maxRecords = 500 # maximum number of records per CSV
$now = Get-Date
foreach ($server in $servers) {
Get-ChildItem "\\$server\$share" -Recurse |
Where-Object { $_.PSIsContainer -eq $False } |
Select-Object DirectoryName, Name, Extension, Length, LastAccessTime,
@{l="HSM";e={ if ( $_.Attributes -match "Compressed") {$true} else {$false} }},
@{l="ACL";e={ (Get-Acl $_.FullName).Owner }} |
ForEach-Object -Begin {$i = 0} -Process {
if ($i % $maxRecords -eq 0) {
if ($writer) {
$writer.Close()
$writer.Dispose()
}
$index = [int][math]::Floor([int]$i/[int]$maxRecords)
$report = 'FileExtAudit_{0}_{1}_{2:HHmm_dd-MM-yyyy}_{3:d3}.csv' -f $server, $share, $now, $index
$writer = [IO.StreamWriter]"$PWD\Logs\$report"
$writer.WriteLine('"DirectoryName","Name","Extension","Length","LastAccessTime","HSM","ACL"')
}
$writer.WriteLine(('"{0}","{1}","{2}","{3}","{4}","{5}","{6}"' -f $_.DirectoryName, $_.Name, $_.Extension, $_.Length, $_.LastAccessTime, $_.HSM, $_.ACL))
$i++
}
if ($writer) {
$writer.Close()
$writer.Dispose()
}
}
在循环中追加可能不是实现这一点的最优雅的方式,但它可以在代码中不做重大更改的情况下工作,同时还可以避免在变量中收集结果:
$maxRecords = 500 # maximum number of records per CSV
$now = Get-Date
foreach ($server in $servers) {
Get-ChildItem "\\$server\$share" -Recurse |
Where-Object { -not $_.PSIsContainer } |
Select-Object DirectoryName, Name, Extension, Length, LastAccessTime,
@{l="HSM";e={ if ( $_.Attributes -match "Compressed") {$true} else {$false} }},
@{l="ACL";e={ (Get-Acl $_.FullName).Owner }} |
ForEach-Object -Begin {$i = 0} -Process {
$index = [int][math]::Floor([int]$i/[int]$maxRecords)
$report = 'FileExtAudit_{0}_{1}_{2:HHmm_dd-MM-yyyy}_{3:d3}.csv' -f $server, $share, $now, $index
$_ | Export-Csv "$PWD\Logs\$report" -NoType -Append
$i++
}
}
从性能PoV来看,使用StreamWriter
将是一个更好的选择(不仅它本身进出速度更快,而且还可以避免重复关闭和重新打开输出文件)。但是,它需要更精细的处理,您还需要自己构建CSV行
$maxRecords = 500 # maximum number of records per CSV
$now = Get-Date
foreach ($server in $servers) {
Get-ChildItem "\\$server\$share" -Recurse |
Where-Object { $_.PSIsContainer -eq $False } |
Select-Object DirectoryName, Name, Extension, Length, LastAccessTime,
@{l="HSM";e={ if ( $_.Attributes -match "Compressed") {$true} else {$false} }},
@{l="ACL";e={ (Get-Acl $_.FullName).Owner }} |
ForEach-Object -Begin {$i = 0} -Process {
if ($i % $maxRecords -eq 0) {
if ($writer) {
$writer.Close()
$writer.Dispose()
}
$index = [int][math]::Floor([int]$i/[int]$maxRecords)
$report = 'FileExtAudit_{0}_{1}_{2:HHmm_dd-MM-yyyy}_{3:d3}.csv' -f $server, $share, $now, $index
$writer = [IO.StreamWriter]"$PWD\Logs\$report"
$writer.WriteLine('"DirectoryName","Name","Extension","Length","LastAccessTime","HSM","ACL"')
}
$writer.WriteLine(('"{0}","{1}","{2}","{3}","{4}","{5}","{6}"' -f $_.DirectoryName, $_.Name, $_.Extension, $_.Length, $_.LastAccessTime, $_.HSM, $_.ACL))
$i++
}
if ($writer) {
$writer.Close()
$writer.Dispose()
}
}
它需要在PowerShell 2.0上运行吗?不,我还可以访问PowerShell 3.0和4.0