I have powershell 4.0 running on windows server 2012 R2 . I want to extract several files from the source folder to destination folder. I have the list of files in CSV template. When I ran the script I got an error like this: Missing '=' operator after key in hash literal. I don;t know what i am doing wrong. Here is my script:
##The external CSV template is like this:
Source_Target_folders "C:\Data_Files\fileone.$TodayDate" = "E:\DEV\_Datafiles\fileone_Extracted" "C:\Data_Files\filetwo.$TodayDate" = "E:\DEV\_Datafiles\filetwo_Extracted" "C:\Data_Files\filethree.$TodayDate" = "E:\DEV\_Datafiles\filethree_Extracted" "C:\Data_Files\filefour.$TodayDate" = "E:\DEV\_Datafiles\filefour_Extracted" "C:\Data_Files\filefive.$TodayDate" = "E:\DEV\_Datafiles\filefive_Extracted"
## Call the CSV
$ZipFiles = Import-csv "c:\PowershellScript\ZipFileFolders.csv"
$ZipFilesAndFolders = @{$ZipFiles}
foreach ($KeyAndValue in $ZipFilesAndFolders.GetEnumerator()) { $ZipFilePath = $KeyAndValue.Key $DestinationPath = $KeyAndValue.Value echo "-------------------------------------------" echo "start extracting" Get-ChildItem $ZipFilePath | % {& "E:\7-Zip\7za.exe" "x" $_.fullname "-o$DestinationPath"} echo "Finish extracting $Dept_name" echo "--------------------------------------------" }
What am I doing wrong? Please help
This '=' is an assignment operation, not a comparison operator. For that you use '-eq' Echo is a batch file thing, and a alias in PS, do use that use the real cmdlet names always. Also, Don't use echo aka Write-Host unless you need to use color. Output results to the screen is the PS default. So, echo / Write-Host is redundant. If those items in the csv are source and destination, they must be split into two variables in order to be properly passed / used.
Thanks for your reply. If I include the source and destination inside an @array, the script works fine. It did not work when the source and destination file is in a CSV file and I import it. Here is how I modified the script using an array:
FilesAndFolders = @{ "C:\Data_Files\fileone.$TodayDate" = "E:\DEV\_Datafiles\fileone_Extracted" "C:\Data_Files\filetwo.$TodayDate" = "E:\DEV\_Datafiles\filetwo_Extracted" "C:\Data_Files\filethree.$TodayDate" = "E:\DEV\_Datafiles\filethree_Extracted" "C:\Data_Files\filefour.$TodayDate" = "E:\DEV\_Datafiles\filefour_Extracted" "C:\Data_Files\filefive.$TodayDate" = "E:\DEV\_Datafiles\filefive_Extracted"}
foreach ($KeyAndValue in $ZipFilesAndFolders.GetEnumerator()) { $ZipFilePath = $KeyAndValue.Key $DestinationPath = $KeyAndValue.Value
echo "-------------------------------------------" echo "start extracting" Get-ChildItem $ZipFilePath | % {& "E:\7-Zip\7za.exe" "x" $_.fullname "-o$DestinationPath"} echo "Finish extracting $Dept_name" echo "--------------------------------------------" }
With this approach the script is working but I dont want to to that. I want to keep the source and destination into a CSV file because I only gave 4 files as example but in reality i have 215 files to extracted. That is why I want to hold it in CSV file and import it. Could you please help?
Your .csv file sounds like .csv file but is not a .csv.
Johnny Blast said:Source_Target_folders "C:\Data_Files\fileone.$TodayDate" = "E:\DEV\_Datafiles\fileone_Extracted" "C:\Data_Files\filetwo.$TodayDate" = "E:\DEV\_Datafiles\filetwo_Extracted"
Only one Header : Source_Target_folders
Only one value : "C:\Data_Files\filetwo.$TodayDate" = "E:\DEV\_Datafiles\filetwo_Extracted"
your .csv file must be like the following :
SourceFile, TargetFolder
C:\Data_Files\filetwo.$TodayDate, E:\DEV\_Datafiles\filetwo_Extracted <=== these are files not folders
Nota1 : the comma (you can put ; if you want but when you'll import the .csv file don't forget -delimiter ";" depending how this .csv has been encoded)
Nota2 : in you .csv file, the " separating each filed are not required.
Johnny Blast said:$ZipFiles = Import-csv "c:\PowershellScript\ZipFileFolders.csv"$ZipFilesAndFolders = @{$ZipFiles}foreach ($KeyAndValue in $ZipFilesAndFolders.GetEnumerator()) { $ZipFilePath = $KeyAndValue.Key $DestinationPath = $KeyAndValue.Value
Nota3 : .Zip files are files not folders !
Nota4 : the coding : Get-ChildItem work fine ... but for directory but it's a non-sense to use it with a file. It returns like Get-Item in this case.
foreach ($file in $zipfiles)
{
Expand-Archive -Path $file.SourceFile -DestinationPath $file.DestinationFolder
Write-verbose "Expanding $($file.Sourcefile) to $($file.DestinationFolder"
(in PS >v5. WIth PS v4 theis cmdlet doesn't exist, use 7-zip is you want or .net class as you want)
}
Nota 5 : in a loop, call the current variable property you want
Please note that in the loop, i'm calling $file.PropertyNamethatImLookingFor.
In the .csv file there are 2 properties called SourceFile and DestinationFolder.
Now it will be fine, and this could be run without any pb.
Regards
Oliv
One more thing : How do you collect information for you .csv file ?
My approach will be:
Get-ChildItem -Path \\path\to\*.zip -file | select-object -property FullName | Export-Csv -Path \\path\to\ZipFileFolders.csv -noTypeInformation (Optional : -delimiter -encoding)
With this, you'll have a correct .csv file, prepare for use. Nota if you use optional params with Export-csv use it again with Import-csv.
Bye. It's late, it's Hot (30°c in my bedroom), but it's time to go to bed. I'm get up like the sun, early in the morning (or late in the night depending of how you see the bottle) :-)
Thank you very much for your input. It make sense to me now. The only things i want to know is that I have Powershell 4.0 and don't have expand-archive cmdlet. I use 7-Zip instead. How am I going to change this line below to 7-Zip ? That is the only part i want to know. Thank you in advance.
I managed to make the script working. It only work if I hard-coded the date (DT190829). If I have the variable $TodayDate the script did not understand and says file could not find. I want to used $TodayDate because I dont want to change the date manually. How to do that? Below is the script that is working.
##Here is the external .CSV file as you suggested.SourceFile, DestinationFolderC:\Data_Files\fileone.$TodayDate, E:\DEV\_Datafiles\fileone_Extracted C:\Data_Files\filetwo.$TodayDate, E:\DEV\_Datafiles\filetwo_ExtractedC:\Data_Files\filethree.$TodayDate, E:\DEV\_Datafiles\filethree_Extracted##Unzip functionAdd-Type -AssemblyName System.IO.Compression.FileSystemfunction Unzip{ param([string]$zipfile, [string]$outpath) [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)}$TodayDate = (Get-Date).ToString('DTyyMMdd') $ZipFiles = Import-csv "Y:\PowershellScript\Development\ZipFileFolders.csv" foreach ($file in $ZipFiles) { ## took the first 3 characters of the extracted files $Dept_name = $file.DestinationFolder.substring(44,3) echo " departname is: $Dept_name" echo "-------------------------------------------" echo "start extracting $Dept_name" Unzip $file.SourceFile $file.DestinationFolder echo "Finish extracting $Dept_name" echo "--------------------------------------------" }