我对脚本非常陌生,我希望有人能给我一些建议。
我自己创建了一个对项目管理有用的PowerShell脚本。脚本分析文件路径以确定它是否太长,并检查文件名是否小于50个字符。此外,它确保没有非法字符和其他事情。所有结果最初都打印到文本文件中。
在PowerShell脚本中,我最初有步骤1、2和3-9生成3个单独的文档。但最终,我决定让所有步骤都写到一个文本文件中。在最后一步中,将导入文本文件以创建CSV。然后按字母顺序对文件路径进行排序,并将返回两个不同结果的任何文件路径合并。最终,用户将引用这个CSV,以便在其媒体存档之前手动更正任何错误。
以下是我遇到的问题。
param(
# $pathToScan Enter the path to scan for file length
[Parameter(Mandatory=$True,Position=0)]
[ValidateNotNull()]
[string]$pathToScan,
#Character Limit to be set
[Parameter(Position=1)]
#[ValidateNotNull()]
[int]$charLimit = 250
)
# File outputs
#$outputEmptyPath = "C:\temp\EmptyPaths_$(Get-Date -Format yyyyMMdd).csv"
#$outputCharPath = "C:\temp\SpecialChars_$(Get-Date -Format yyyyMMdd).csv"
$outputFilePath = "C:\temp\PathLengths_$(Get-Date -Format yyyyMMdd).txt"
# Use this switch to display to screen. Can ignore this for now.
$writeToConsoleAsWell = $false # Writing to the console will be much slower.
# Open a new file stream (nice and fast) and write all the paths and their lengths to it.
$outputFileDirectory = Split-Path $outputFilePath -Parent
if (!(Test-Path $outputFileDirectory)) { New-Item $outputFileDirectory -ItemType Directory }
$streamPath = New-Object System.IO.StreamWriter($outputFilePath, $false)
#$streamChar = New-Object System.IO.StreamWriter($outputFilePath, $false)
#$streamEmpty = New-Object System.IO.StreamWriter($outputFilePath, $false)
# STEP 1 - Check for empty paths.
((Get-ChildItem -Path $pathToScan -Recurse | Where-Object {$_.PSIsContainer -eq $True}) | Where-Object {$_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0}) | ForEach-Object {
$emptyPaths = $_.FullName
if ($emptyPaths) {
$streamPath.WriteLine("$emptyPaths , empty folder")
}
}
# STEP 2 - Show for long paths. (default=250 characters)
Get-ChildItem -Path $pathToScan -Recurse | Select-Object -Property BaseName, FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}} | Sort-Object -Property FullNameLength -Descending | ForEach-Object {
$fileName = $_.BaseName
$filePath = $_.FullName
$length = $_.FullNameLength
if ($length -gt $charLimit) {
$string = "$length : $filePath"
# Write to the Console.
if ($writeToConsoleAsWell) { Write-Host $string }
#Write to the file.
$streamPath.WriteLine("$filepath ,, file path too long")
}
#STEP 3 - Check for special characters. Allowed characters are Alphanumerics, single space, dashes, underscores, periods
if ($filename -match '[^a-zA-Z0-9 -_.]') {
$streamPath.WriteLine("$filepath ,,, has special characters")
}
#STEP 4 - Check for double spaces, dashes, periods and underscores
if ($filepath -match '\s{2,}|\-{2,}|\.{2,}|_{2,}') {
$streamPath.WriteLine("$filepath ,,,, has double spaces/dashes/periods/underscores")
}
#STEP 5 - check for more than 50 characters
if ($filename -match '[^\\]{51,}\.[a-zA-Z0-9]{2,7}$') {
$streamPath.WriteLine("$filepath ,,,,, exceeds 50 characters")
}
#STEP 6 - check for empty space at end of file or folder name
if ($filename -match '(\s+$)|(\s+\\)|(\s+\.)') {
$streamPath.WriteLine("$filepath ,,,,,, name has space at end")
}
#STEP 7 - check for zip and other archived files
if ($filename -match '(?i)\.zip$|(?i)\.tar.gz$|(?i)\.gz$|(?i)__MACOSX$') {
$streamPath.WriteLine("$filepath ,,,,,,, unzip files before archiving")
}
#step 8 - check for cache and render files
if ($filename -match '(?i)\.cfa$|(?i)\.pek$|(?i)\.xmp$') {
$streamPath.WriteLine("$filepath ,,,,,,,, delete cache and render files")
}
#step 9 - check for Windows hidden files
if ($filename -match '(?i)\._|thumbs.db') {
$streamPath.WriteLine("$filepath ,,,,,,,,, delete hidden files")
}
}
Start-Sleep -Seconds 30
#step 10 - Merge and sort results
Import-Csv -Path "C:\temp\PathLengths_$(Get-Date -Format yyyyMMdd).txt" -Header 'Path', 'Empty Folder', 'Long File Path', 'Special Characters', 'Double Spaces, Dashes, Periods and Underscores', 'Exceeds 50 Characters', 'Name Has Space at End', 'Zip File', 'Cache and Render Files', 'Windows Hidden Files' | sort 'Path' | Group-Object 'Path' | ForEach-Object {
[PsCustomObject]@{
'Path' = $_.Name
'Empty Folder' = $_.Group.'Empty Folder' -join ','
'Long File Path' = $_.Group.'XMP File' -join ',,'
'Special Characters' = $_.Group.'Special Characters' -join ',,,'
'Double Spaces, Dashes, Periods and Underscores' = $_.Group.'Double Spaces, Dashes, Periods and Underscores' -join ',,,,'
'Exceeds 50 Characters' = $_.Group.'Exceeds 50 Characters' -join ',,,,,'
'Name Has Space at End' = $_.Group.'Name Has Space at End' -join ',,,,,,'
'Zip File' = $_.Group.'Zip File' -join ',,,,,,,'
'Cache and Render Files' = $_.Group.'Cache and Render Files' -join ',,,,,,,,'
'Windows Hidden Files' = $_.Group.'Windows Hidden Files' -join ',,,,,,,,,'
}
} | Export-Csv "C:\temp\PathLengths_$(Get-Date -Format yyyyMMdd)-SORTED_FINAL.csv" -Delimiter ',' -NoTypeInformation发布于 2020-07-11 09:48:15
您不应该创建这样的临时csv文件,然后将其转换为CSV,在那里您可以使用PSCustomObject和Export立即完成它。
创建类似csv的临时文件的方式使您很容易混淆逗号的数量,从而导致字段的不对齐。
另外,我建议不要在CSV头中使用逗号(也许还可以缩短它们,但这取决于您)。
尝试:
param(
# $pathToScan Enter the path to scan for file length
[Parameter(Mandatory = $true, Position = 0)]
[ValidateScript({ Test-Path -Path $_ -PathType Container })]
[string]$pathToScan,
#Character Limit to be set
[int]$charLimit = 250
)
# File output
$outputFile = "C:\temp\PathLengths_$(Get-Date -Format yyyyMMdd).csv"
# collect custom objects
$result = Get-ChildItem -Path $pathToScan -Recurse -Force | ForEach-Object {
# create the output object.
$obj = [PsCustomObject]@{
'Path' = $_.FullName
'ObjectType' = if ($_.PSIsContainer) {'Folder'} else {'File'}
'Empty Folder' = $null
'Long File Path' = $null
'Special Characters' = $null
'Double Spaces_Dashes_Periods_Underscores' = $null
'Exceeds 50 Characters' = $null
'Name Has Space at End' = $null
'Zip File' = $null
'Cache and Render Files' = $null
'Windows Hidden Files' = $null
}
# STEP 1 - Check for empty paths.
if ($_.PSIsContainer -and $_.GetFileSystemInfos().Count -eq 0) { $obj.'Empty Folder' = 'empty folder' }
# STEP 2 - Show for long paths. (default=250 characters)
if ($_.FullName.Length -gt $charLimit) { $obj.'Long File Path' = 'path too long' }
#STEP 3 - Check for special characters. Allowed characters are Alphanumerics, single space, dashes, underscores, periods
if ($_.BaseName -match '[^-a-z0-9 _.]') { $obj.'Special Characters' = 'has special characters' }
#STEP 4 - Check for double spaces, dashes, periods and underscores
if ($_.BaseName -match '[-\s._]{2,}') { $obj.'Double Spaces_Dashes_Periods_Underscores' = 'has double spaces/dashes/periods/underscores' }
#STEP 5 - check for more than 50 characters
# This is a weird check.. Why not simply if ($_.Name.Length -gt 50) ???
if ($_.Name -match '[^\\]{51,}\.[a-z0-9]{2,7}$') { $obj.'Exceeds 50 Characters' = 'exceeds 50 characters' }
#STEP 6 - check for empty space at end of file or folder name
if ($_.Name -match '\s$') { $obj.'Name Has Space at End' = 'name ends in whitespace' }
# these are for files only:
if (!$_.PSIsContainer) {
#STEP 7 - check for zip and other archived files
if ($_.Name -match '\.zip$|\.tar|\.gz$|__MACOSX$') { $obj.'Zip File' = 'unzip files before archiving' }
#STEP 8 - check for cache and render files
if ('.cfa', '.pek', '.xmp' -contains $_.Extension) { $obj.'Cache and Render Files' = 'delete cache and render files' }
#STEP 9 - check for Windows hidden files
if ($_.Attributes -band [System.IO.FileAttributes]::Hidden) { $obj.'Windows Hidden Files' = 'delete hidden files' }
}
# output the object, only if there is some value of interest
# (the first two properties 'Path' and 'ObjectType' are general info, so we disregard those here)
if (($obj.PsObject.Properties | Select-Object -Skip 2).Value -join '' -ne '') {
$obj
}
}
if ($result) { $result | Export-Csv -Path $outputFile -NoTypeInformation }正如您所看到的,我已经更改了一些测试:
(?i)上删除-match,因为这在默认情况下是不区分大小写的。-移到正则表达式(如[^-a-z0-9 _.] )的前面,因为否则它将被解释为regex范围,而不是减号本身。https://stackoverflow.com/questions/62845861
复制相似问题