Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly -filter multiple strings in a PowerShell copy script

I am using the PowerShell script from this answer to do a file copy. The problem arises when I want to include multiple file types using the filter.

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

works like a dream. However, The problem arises when I want to include multiple file types using the filter.

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 } 

Gives me the following error:

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 

I have various iterations of parentheses, no parentheses, -filter, -include, defining the inclusions as variable (e.g., $fileFilter) and each time get the above error, and always pointing to whatever follows -filter.

The interesting exception to that is when I code -filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*". There are no errors, but I and get no results and nothing back to the console. I suspect I've inadvertently coded an impicit and with that statement?

So what am I doing wrong, and how can I correct it?

like image 442
dwwilson66 Avatar asked Sep 04 '13 14:09

dwwilson66


People also ask

How do I replace multiple characters in a string in PowerShell?

Replace Multiple Instance Strings Using the replace() Function in PowerShell. Since the replace() function returns a string, to replace another instance, you can append another replace() function call to the end. Windows PowerShell then invokes the replace() method on the original output.

How do I pass multiple command line arguments in PowerShell?

To pass multiple parameters you must use the command line syntax that includes the names of the parameters. For example, here is a sample PowerShell script that runs the Get-Service function with two parameters. The parameters are the name of the service(s) and the name of the Computer.

What does $_ mean in PowerShell?

The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.

How do I concatenate strings in PowerShell?

In PowerShell, string concatenation is primarily achieved by using the “+” operator. There are also other ways like enclosing the strings inside double quotes, using a join operator, or using the -f operator. $str1="My name is vignesh."


2 Answers

-Filter only accepts a single string. -Include accepts multiple values, but qualifies the -Path argument. The trick is to append \* to the end of the path, and then use -Include to select multiple extensions. BTW, quoting strings is unnecessary in cmdlet arguments unless they contain spaces or shell special characters.

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

Note that this will work regardless of whether $originalPath ends in a backslash, because multiple consecutive backslashes are interpreted as a single path separator. For example, try:

Get-ChildItem C:\\\\\Windows 
like image 191
Adi Inbar Avatar answered Sep 24 '22 07:09

Adi Inbar


Something like this should work (it did for me). The reason for wanting to use -Filter instead of -Include is that include takes a huge performance hit compared to -Filter.

Below just loops each file type and multiple servers/workstations specified in separate files.

##   ##  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 
like image 44
Kevin Avatar answered Sep 23 '22 07:09

Kevin