Basic File Operations - powershell

Please refer to my first code in PS, below:
I created a Test.ps1 file and included the following code:
$path = D:\Five-Levels_Deep_Subfolder\Data
$file = A_Very_Long_INI_FileName.ini
#If $file exists, Delete it:
if (Test-Path + $path) { Remove-Item $path + $file }
#Run the following Application:
& $path + myApplication.exe
But, the result tried to terrify me with a number of horrible error messages. As a matter of fact, none of the above lines of code was error-free.
Please bear with a toddler in PS, and help me to make it a great success :-).

Try this
$path = "D:\Five-Levels_Deep_Subfolder\Data"
$file = "A_Very_Long_INI_FileName.ini"
$filepath = join-path $path $file
#If $filepath exists, Delete it:
if (Test-Path $filepath) { Remove-Item $filepath}
#Run the following Application:
& ($path + "\myApplication.exe")

Related

Powershell Script, 2x variable in foreach loop

I'm losing my mind. I have to confess I'm a typical copy-paste non-scripting guy, stand here with something new I cannot solve. I want to work with ocrmypdf.exe where I have to read a network-folder for PDFs and put it on a subfolder.
ocrmypdf works simple: ocrmypdf.exe
I have 3 variables like:
$source = #(Get-ChildItem -Path 'X:\OCR\*.pdf') # <-- here are my files, filtered for pdfs
$destname = "X:\ocr\done" #destination-folder where the pdf-files should be written in
$destfiles = foreach ($file in $source) {"$destname\$($file.name)"} # <--- destination path + the same source-file-name
when I have to run a command-exe in Powershell, I should run it like
Foreach ($a in $source)
{
& $command $param
}
where $command and $param is (not) something like this:
$command = 'ocrmypdf.exe'
$param = '$source', '$destfiles'
but as I already know this is not working because the foreachloop can not work with my variables.
Could someone please help me to solve this? Yes my laziness reading a powershell-book comes over and over me now, but I try my luck anyway :)
Thank you in advance
You can supply as many arguments to a command invocation as you want:
$source = #(Get-ChildItem -Path 'X:\OCR\*.pdf')
$destname = "X:\ocr\done"
$command = 'ocrmypdf.exe'
foreach ($file in $source) {
$sourcePath = $file.FullName
$destPath = Join-Path $destname $file.name
# pass both arguments to command
& $command $sourcePath $destPath
}

Powershell: Converting Headers from .msg file to .txt - Current directory doesn't pull header information, but specific directory does

So I am trying to make a script to take a batch of .msg files, pull their header information and then throw that header information into a .txt file. This is all working totally fine when I use this code:
$directory = "C:\Users\IT\Documents\msg\"
$ol = New-Object -ComObject Outlook.Application
$files = Get-ChildItem $directory -Recurse
foreach ($file in $files)
{
$msg = $ol.CreateItemFromTemplate($directory + $file)
$headers = $msg.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E")
$headers > ($file.name +".txt")
}
But when I change the directory to use the active directory where the PS script is being run from $directory = ".\msg\", it will make all the files into text documents but they will be completely blank with no header information. I have tried different variations of things like:
$directory = -Path ".\msg\"
$files = Get-ChildItem -Path $directory
$files = Get-ChildItem -Path ".\msg\"
If anyone could share some ideas on how I could run the script from the active directory without needing to edit the code to specify the path each location. I'm trying to set this up so it can be done by simply putting it into a folder and running it.
Thanks! Any help is very appreciated!
Note: I do have outlook installed, so its not an issue of not being able to pull the headers, as it works when specifying a directory in the code
The easiest way might actually be to do it this way
$msg = $ol.CreateItemFromTemplate($file.FullName)
So, the complete script would then look something like this
$directory = ".\msg\"
$ol = New-Object -ComObject Outlook.Application
$files = Get-ChildItem $directory
foreach ($file in $files)
{
$msg = $ol.CreateItemFromTemplate($file.FullName)
$headers = $msg.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E")
$headers > ($file.name +".txt")
}
All that said, it could be worthwhile reading up on automatic variables (Get-Help about_Automatic_Variables) - for instance the sections about $PWD, $PSScriptRoot and $PSCommandPath might be useful.
Alternative ways - even though they seem unnecessarily complicated.
$msg = $ol.CreateItemFromTemplate((Get-Item $directory).FullName + $file)
Or something like this
$msg = $ol.CreateItemFromTemplate($file.DirectoryName + "\" $file)

Looping through File Groups such as FileGroup159, FileGroup160, etc. in Powershell

So I got the code to work how I like it for individual files. Based on some of the suggestions below, I was able to come up with this:
$Path = "C:\Users\User\Documents\PowerShell\"
$Num = 160
$ZipFile = "FileGroup0000000$Num.zip"
$File = "*$Num*.txt"
$n = dir -Path $Path$File | Measure
if($n.count -gt 0){
Remove-Item $Path$ZipFile
Compress-Archive -Path $Path$File -DestinationPath $Path
Rename-Item $Path'.zip' $Path'FileGroup0000000'$Num'.zip'
Remove-Item $Path$File
}
else {
Write-Output "No Files to Move for FileGroup$File"
}
The only thing I need to do now is have $Num increment after the program finishes each time. Therefore the program will run, and then move $Num to 160, 161, etc. and I will not have to re initiate the code manually. Thanks for the help so far.
Your filename formatting should go inside the loop and you should use the Format operator -f to get the preceding zeros, like:
159..1250 | ForEach-Object {
$UnzippedFile = 'FileGroup{0:0000000000}' -f $_
$ZipFile = "$UnzippedFile.zip"
Write-Host "Unzipping: $ZipFile"
# Do your thing here
}

powershell : command does not work when called inside a loop

The following command does work in a powershell console
Restore-SvnRepository D:\temp\Backup\foo.vsvnbak
(Restore-SvnRepository is a command that comes with visualsvn, it expects a path or unc to a file to be restored as parameter)
As I need to execute this command for a large number of files (>500) I embedded it inside a powershell loop but then it doesn't work
$fileDirectory = "D:\temp\Backup"
$files = Get-ChildItem $fileDirectory -Filter "*.vsvnbak"
foreach($file in Get-ChildItem $fileDirectory)
{
$filePath = $fileDirectory + "\" + $file;
# escape string for spaces
$fichier = $('"' + $filepath + '"')
# write progress status
"processing file " + $fichier
# command call
Restore-SvnRepository $fichier
}
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
I don't understand why this does not work. The loop and filename looks good but when executed, each command throws the following error message
Restore-SvnRepository : Parameter 'BackupPath' should be an absolute or UNC path to the repository
backup file you would like to restore: Invalid method Parameter(s) (0x8004102F)
Could you help me?
EDIT
It looks like that I was confused by Get-ChildItem that return a System.IO.FileSystemInfo rather than a string.
I didn't notice because of a implicit call to the ToString() when writing to the console that made me think I was dealing with string (rather than FSI)
The following code works
$fileDirectory = "D:\temp\Backup\"
$files = Get-ChildItem $fileDirectory -Filter "*.vsvnbak"
foreach($file in $files)
{
# $file is an instance of System.IO.FileSystemInfo,
# which contains a FullName property that provides the full path to the file.
$filePath = $file.FullName
Restore-SvnRepository -BackupPath $filePath
}
$file isn't a string, it's an object containing file data.
You can simplify your code as follows:
$fileDirectory = "D:\temp\Backup"
$files = Get-ChildItem $fileDirectory -Filter "*.vsvnbak"
foreach($file in $files)
{
# $file is an instance of System.IO.FileSystemInfo,
# which contains a FullName property that provides the full path to the file.
$filePath = $file.FullName
# ... your code here ...
}

Can't create a folder, based on file name

I'm trying to create a script that will copy over specific folders and files in C:\Users\ from three terminal servers, onto a file server.
The problem is, that I create the folders on the file server based on the name of the folder i'm copying. And the script fails when it trys to create a folder on the file server, based on a file instead of a folder.
(Sorry that the text on the image is in Danish! - Hope it still might help.)
I hope the script makes more sense, thanks! :)
Image: http://imgur.com/kxbzXXK
$ServerList = "\\ServerA", "\\ServerB" #Angiv hvilke servere der skal kopires fra, f.eks "\\serverA", "\\serverB".
$FromDir = "\C$\Users\" #Angiv hvilken sti der skal kopires fra, f.eks "\c$\TEST"
$ToDir = "C:\DavidTest_DataMappe\"
foreach ($Server in $ServerList)
{
$RemotePath = $Server + $FromDir
$RemoteDirs = Get-ChildItem $RemotePath |? {$_.mode -match "d"}
foreach($Username in $RemoteDirs | where-object {$_.Name.Length -le 4})
{
$FileList = "\Desktop",
#"\Documents",
#"\Music",
#"\Pictures",
#"\Videos",
#"\Favorites",
#"\Links"#,
"\AppData\Local\Google\Chrome\User Data\Default\Bookmarks",
"\AppData\Roaming\Mozilla\Firefox\Profiles\*.default\places.sqlite"
foreach($File in $FileList)
{
ECHO "Copying folder"
$ToDirPlusUser = $ToDir + $Username + $File
$CopyFile = $RemotePath + $Username + $File
Copy-Item $CopyFile $ToDirPlusUser -Recurse
}
}
}
ECHO "***********"
ECHO "***********"
ECHO "Script Done"
ECHO "***********"
ECHO "***********"
Also add this line above copy-item
Write-Host "Copy-Item $CopyFile $ToDirPlusUser -Recurse"
It will help you zone in on which file/directory is creating the error.