web-dev-qa-db-ja.com

PowerShellコピースクリプトで複数の文字列を適切にフィルター処理する方法

this answer のPowerShellスクリプトを使用して、ファイルのコピーを実行しています。この問題は、フィルターを使用して複数のファイルタイプを含める場合に発生します。

Get-ChildItem $originalPath -filter "*.htm"  | `
   foreach{ $targetFile = $htmPath + $_.FullName.SubString($originalPath.Length); ` 
 New-Item -ItemType File -Path $targetFile -Force;  `
 Copy-Item $_.FullName -destination $targetFile }

夢のように機能します。ただし、フィルターを使用して複数のファイルタイプを含める場合に問題が発生します。

Get-ChildItem $originalPath ` 
  -filter "*.gif","*.jpg","*.xls*","*.doc*","*.pdf*","*.wav*",".ppt*")  | `
   foreach{ $targetFile = $htmPath + $_.FullName.SubString($originalPath.Length); ` 
 New-Item -ItemType File -Path $targetFile -Force;  `
 Copy-Item $_.FullName -destination $targetFile }

次のエラーが表示されます。

Get-ChildItem : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Filter'. Specified method is not supported.
At F:\data\foo\CGM.ps1:121 char:36
+ Get-ChildItem $originalPath -filter <<<<  "*.gif","*.jpg","*.xls*","*.doc*","*.pdf*","*.wav*",".ppt*" | `
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.GetChildItemCommand

括弧のさまざまな反復があり、括弧はありません、-filter-include、変数として包含を定義し(たとえば、$fileFilter)、毎回上記のエラーを取得し、常に以下を指します-filter

興味深い例外は、-filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*"をコーディングするときです。エラーはありませんが、結果は得られず、コンソールには何も戻りません。そのステートメントで暗黙的にandを誤ってコーディングしたのではないでしょうか?

だから私は何を間違えているのですか、どうすれば修正できますか?

68
dwwilson66

-Filterは、単一の文字列のみを受け入れます。 -Includeは複数の値を受け入れますが、-Path引数を修飾します。トリックは、パスの最後に\*を追加し、-Includeを使用して複数の拡張子を選択することです。ところで、スペースまたはシェルの特殊文字が含まれていない限り、コマンドレット引数で文字列を引用する必要はありません。

Get-ChildItem $originalPath\* -Include *.gif, *.jpg, *.xls*, *.doc*, *.pdf*, *.wav*, .ppt*

これは$ originalPathがバックスラッシュで終わるかどうかに関係なく機能することに注意してください。複数の連続するバックスラッシュは単一のパス区切り文字として解釈されるためです。たとえば、試してみてください:

Get-ChildItem C:\\\\\Windows
162
Adi Inbar

このような何かが動作するはずです(私にとってはうまくいきました)。 -Filterの代わりに-Includeを使用する理由は、includeが-Filterと比較して大きなパフォーマンスヒットを取るためです。

以下は、各ファイルタイプと、個別のファイルで指定された複数のサーバー/ワークステーションをループします。

##  
##  This script will pull from a list of workstations in a text file and search for the specified string


## Change the file path below to where your list of target workstations reside
## Change the file path below to where your list of filetypes reside

$filetypes = gc 'pathToListOffiletypes.txt'
$servers = gc 'pathToListOfWorkstations.txt'

##Set the scope of the variable so it has visibility
set-variable -Name searchString -Scope 0
$searchString = 'whatYouAreSearchingFor'

foreach ($server in $servers)
    {

    foreach ($filetype in $filetypes)
    {

    ## below creates the search path.  This could be further improved to exclude the windows directory
    $serverString = "\\"+$server+"\c$\Program Files"


    ## Display the server being queried
    write-Host “Server:” $server "searching for " $filetype in $serverString

    Get-ChildItem -Path $serverString -Recurse -Filter $filetype |
    #-Include "*.xml","*.ps1","*.cnf","*.odf","*.conf","*.bat","*.cfg","*.ini","*.config","*.info","*.nfo","*.txt" |
    Select-String -pattern $searchstring | group path | select name | out-file f:\DataCentre\String_Results.txt

    $os = gwmi win32_operatingsystem -computer $server
    $sp = $os | % {$_.servicepackmajorversion}
    $a = $os | % {$_.caption}

    ##  Below will list again the server name as well as its OS and SP
    ##  Because the script may not be monitored, this helps confirm the machine has been successfully scanned
        write-Host $server “has completed its " $filetype "scan:” “|” “OS:” $a “SP:” “|” $sp


    }

}
#end script
2
Kevin