Add double quotes to variable to escape space - powershell

I am running a script which has $FileName variable containing the absolute path with spaces. Due to the space within the directory name and file name, the script fails to executes without finding the actual path. All I need is to add $FilePath within double quotes. How should I append double quotes in the beginning and end of a string?
For example
"X:\Movies\File One\File One.txt"
Script:
$FilePath = Join-Path $Path $($Dir + "\" + $File + “.txt”)
$FilePath
Current OutPut:
X:\Movies\File One\File One.txt

In addition to the backtick escape character (`), you can use the -f format operator:
$FilePath = Join-Path $Dir -ChildPath "$File.txt"
$FilePathWithQuotes = '"{0}"' -f $FilePath
This will ensure that $FilePath is expanded before being placed in the string

$FilePath = Join-Path $Path $($Dir + "\" + $File + “.txt”)
"`"$FilePath`""
...would output...
"X:\Movies\File One\File One.txt"
This is an example of variable expansion in strings.
Of course, if the path you want to quote could contain " quotes itself, for example in a future "powershell for linux", you'd need to escape the " in a context specific way.

Any one of these should work:
$FilePath1 = """" + (Join-Path $Path $($Dir + "\" + $File + ".txt")) + """"
$FilePath2 = "`"" + (Join-Path $Path $($Dir + "\" + $File + ".txt")) + "`""
$FilePath3 = '"{0}"' -f (Join-Path $Path $($Dir + "\" + $File + ".txt"))
$FilePath4 = '"' + (Join-Path $Path $($Dir + "\" + $File + ".txt")) + '"'
$FilePath5 = [char]34 + (Join-Path $Path $($Dir + "\" + $File + ".txt")) + [char]34

fastest solution (but a bit ugly) to add quotes around any string:
$dir = "c:\temp"
$file = "myfile"
$filepath = [string]::Join("", """", $dir,"\", $file, ".txt", """")

Related

Azure DataLake gen2 Powershell Limits

i'm getting a limitation with cmdlet of Azure Datalake gen2:
https://learn.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-directory-file-acl-powershell
I'm using this cmdlet:
Get-AzDataLakeGen2ChildItem -Context $ctx -FileSystem $filesystemName -Path $dirname -Recurse -FetchProperty
to get all file and folder ACL from root but it has 5000 object limitation and it show this message when i run it to a folder with more than 5000 object:
basically, with that token i can continue from the last extracted(manually is crazy to do becouse maybe we have million file on datalake).
Is possible to avoid it or to loop in some way?
Here the script that i'm using(it works fine, i don't report all file ma only folder from root):
$dir = Get-AzDataLakeGen2ChildItem -Context $ctx -FileSystem "datalake" -Recurse -FetchProperty
$FileOutdtk = "C:\Temp\file.csv"
Clear-Content $FileOutdtk
Add-Content $FileOutdtk ('"Path"^"IsDirectory"^"Owner"^"DisplayName Owner"^"Owner Permissions"^"Group"^"DefaultScope"^"AccessControlType"^"EntityId"^"DisplayName Gruppo"^"PermissionsACL"')
foreach ($directory in $dir) {
if($directory.IsDirectory -eq $true){
if($directory.Owner -imatch "superuser"){
foreach ($ACLs in $directory.ACL){
if($ACLs.EntityId -eq $null ){
Add-Content $FileOutdtk ('"' + $directory.Path + '^' + $directory.IsDirectory + '^' + $directory.Owner + '^' + "" + '^' + $directory.Permissions.Owner + '^' + $directory.Group + '^' + $ACLs.DefaultScope + '^' + $ACLs.accesscontroltype + '^' + $ACLs.EntityId + '^' + "" + '^' + $ACLs.Permissions + '"')
}
else{
$GruppiEntityId = Get-AzureADGroup -ObjectId $ACLs.EntityId
Add-Content $FileOutdtk ('"' + $directory.Path + '^' + $directory.IsDirectory + '^' + $directory.Owner + '^' + "" + '^' + $directory.Permissions.Owner + '^' + $directory.Group + '^' + $ACLs.DefaultScope + '^' + $ACLs.accesscontroltype + '^' + $ACLs.EntityId + '^' + $GruppiEntityId.displayname + '^' + $ACLs.Permissions + '"')
}
}
How i can loop that cmdlet to get up to 5000 object?
Thanks a lot
If you want to list all items in one Azure data lake gen2 folder, please refer to the following script
$storageAccount = Get-AzStorageAccount -ResourceGroupName "<>" -AccountName "<>"
$ctx = $storageAccount.Context
$fileSystem="test"
$dirName="testFolder"
$Token = $Null
$Max=2000
do{
$items=Get-AzDataLakeGen2ChildItem -Context $ctx -FileSystem $fileSystem -Path $dirName -Recurse -FetchProperty -ContinuationToken $Token -MaxCount $Max
$items
if($items.Length -le 0) { Break;}
$Token = $items[$items.Count -1].ContinuationToken;
}
While ($Token -ne $Null)

Test-Path - Illegal characters in path when using a variable

I m fairly new to PowerShell and I apologize in advance if this is a dumb question.
I am trying to construct a new destination/filename where I take the old filename and increment its prefix with +1
$destination = Split-Path -Path 'C:\Users\tom\Desktop\test\0_InstalledPrograms.log'
$file = split-path "C:\Users\tom\Desktop\test\0_InstalledPrograms.log" -Leaf
$array = $file -split '_'
$prefix = $array[0] + 1
$suffix = $array[1]
$newFile = $prefix + '_' + $suffix
$newFile = Out-String -InputObject $newFile
$destination = $destination + '\' + $newFile
Test-Path $destination
Test-Path : Illegal characters in path.
At C:\Users\tom\Desktop\incrementFileName.ps1:18 char:1
+ Test-Path $destination
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (C:\Users\lgranc...dPrograms.log
:String) [Test-Path], ArgumentException
+ FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.TestPathCommand
False
This statement:
$newFile = Out-String -InputObject $newFile
adds a new line (CR+LF) to the string, and is completely unnecessary ($newFile is already a string).
Remove that line and it'll work :)
You can do it easily as follows:
$file = "C:\Users\tom\Desktop\test\0_InstalledPrograms.log"
$splittedName = (Split-Path $file -leaf).split('_')
$newFileName = [string]([int]$splittedName[0] + 1) +'_'+ $splittedName[1]
Move-Item -Path $file -Destination (Join-Path (Split-path $file) -ChildPath $newFileName)

aws cli (on powershell) waiting for the cp to finishe before doing next command

How do I check if the copy was successful before the script goes to the next command?
$src_dir_local = 'D:\temp\tobemoved\'
$dst_dir_local = 'D:\temp\moved\'
$log_dir = 'D:\temp\log\'
$log_file = 'backup.log'
$ofs_char = "`n"
$curr_date = Get-Date -UFormat '%Y-%m-%d'
$curr_date_time = Get-Date
$s3_bucket = 's3://mybucket/'
$s3_storage_class = 'STANDARD_IA'
$files = Get-ChildItem $src_dir_local
write-output $src_dir_local + $file + $curr_date
write-output $s3_command
aws s3 ls
write-output 'looping through files....'
foreach($f in $files){
$outputfilename = $f.Name
$s3_move_command = 'time aws s3 cp --quiet' + ($src_dir_local + $outputfilename + ' ' + $s3_bucket + $curr_date + '/' + $outputfilename + ' --storage-class ' + $s3_storage_class)
write-output $outputfile
write-output 'Start process'
Invoke-Expression $s3_move_command
move-item -path ($src_dir_local + $outputfilename) -destination ($dst_dir_local + '_mvd_' + $outputfilename) -whatif
write-output 'End process'
write-output 'Start moving process'
$log_message = ($ofs_char + 'File moved ' + $outputfile + ' ' + $((Get-Date).ToString()))
if(Test-Path ($log_dir + $log_file)){
Add-Content ($log_dir + $log_file) $log_message
}else{
New-Item -path $log_dir -name $log_file -type 'file' -value 'Initial log '
Add-Content ($log_dir + $log_file) $log_message
}
}
In general, you would write:
aws s3 cp $src $dst
If ($lastexitcode -eq 0) {
...
} Else {
...
}
See the docs here.
If you must use Invoke-Expression, then see the linked Stack Overflow answer.

Move-Item to correct Destination

The Script:
Creates a list of folders based on the filenames in the scripts root directory, each folder breaks down the name by "Year/Month/Day"
Moves each file to the designated folder
Error Message:
CategoryInfo : ObjectNotFound:
(S:\Data\TECHNOL...59_20180108.txt:String)
[Move-Item], ItemNotFoundException FullyQualifiedErrorId :
PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
My Issue
The files will not move to the correct endpath
#Create Directory
Set-StrictMode -Version 2
$rootPath = split-path -parent $MyInvocation.MyCommand.Definition
cd $rootPath
$FileNameArray = Get-ChildItem -Filter "*.txt"
$FileNameArray = $FileNameArray -replace "....$"
$FileNameArray = $FileNameArray -replace "^59_"
Foreach($f in $FileNameArray)
{
$Year = $f -replace "^\d{0}|\d{4}$" #"....$"
$Month = $f -replace "^\d{4}|\d{2}$"
$Month = $Month | sort -Unique
$Day = $f -replace "^\d{6}|\d{0}$"
#Loop 2a
Foreach($m1 in $Month){
#Loop 2a-a
Foreach($d1 in $Day){
Move-Item -Path ($rootPath + '\59_' + $file + '.txt')
-Destination ($rootPath + '\' + $Year + '\' + $m1 + '\' + $d1)
}
}
}
Apologies for the spaghetti code & simple question, I am new to both Computer Science and PowerShell.
The following script has two security features:
The MD command has a trailing -confirm you have to answer
The Move-Item has a -WhatIf which shows what would be done without the Parameter
If the script works OK, remove them both.
## Q:\Test\2018\05\03\SO_50158185.ps1
Set-StrictMode -Version 2
$rootPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
cd $rootPath
Get-ChildItem "59_20[0-9][0-9][0-1][0-9][0-3][0-9].txt" |
Where-Object {$_.BaseName -Match '59_(?<year>\d{4})(?<Month>\d{2})(?<Day>\d{2})'}|
ForEach-Object {
$DestDir = Join-Path $rootPath ("{0}\{1}\{2}" -f $Matches.Year,$Matches.Month,$Matches.Day)
If (!(Test-Path $DestDir)) {MD $DestDir -Confirm| Out-Null}
$_ | Move-Item -Destination $DestDir -WhatIf
}
Figured it out guys! Just needed to change $file to $f. Thanks for all the help.

Powershell Copying Files Script

I am trying to copy, and rename multiple files to miltiple folders. The folders will be labeled sequentially like the files. For example I need to copy Reports.txt change the name to Reports_NW01_20120219.txt to a folder called NW01 then the same process for NW02-NW18. The folder and file names increase by 1. I am new to powershell so please spare me. I have pasted what I have below. I am attempting to read in the date and then append it to the file name. I am at a complete loss now. So any help is appreciated:
$date = read-host "Enter date of the report YYYYMMDD"
write-host $date
for ($Counter = 1; $Counter -le 1; $Counter++)
{
#Destination for files
$DropDirectory = "C:\Users\dh0520\Documents\Powershell Staging\"
#Current Location of the files
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW01\Reports.txt"
if ($Counter -lt 10) {
$Destination = $DropDirectory+'NW0' + $Counter
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW0" + $Counter + "\Reports.txt"
Copy-Item $file.FullName ($Destination + $file.BaseName + "_NW0" + $Counter + "_" + $date +".txt")
}
If ($Counter -ge 10) {
$Destination = $DropDirectory+'NW' + $Counter
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW" + $Counter + "\Reports.txt"
Copy-Item $file.FullName ($Destination + $file.BaseName + "_NW" + $Counter + "_" + $date +".txt")
}
}
I assume you are getting errors with the get-childItem. It is because you cant build the path like that. Try it this way:
$file = Get-ChildItem -Path "C:\test\NW0$($Counter)\Reports.txt"
and this way:
$file = Get-ChildItem -Path "C:\test\NW$($Counter)\Reports.txt"