nested mkdir inside directory with spaces - powershell

This command:
mkdir "watermelon fun"\example
Outputs the following:
PS C:\Users\Andrés\temp> mkdir "watermelon fun"\example
mkdir : No se encuentra ningún parámetro de posición que acepte el argumento '\example'.
En línea: 1 Carácter: 1
+ mkdir "watermelon fun"\example
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [mkdir], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,mkdir
Is there a way you can create a nested directory, being one of these a multiple word directory?

You have to surround the complete path with quotes:
mkdir "watermelon fun\example"

Consider using the Join-Path cmdlet to combine a path.
$path = join-path 'watermelon fun' 'example'
New-Item -Path $path -ItemType Directory -Force

Related

Running a Powershell command with a variable -Path parameter

Can someone please explain the following behaviour to me?
PS C:\Users\Kenny> $filePath = "C:\\Complicated.File.Path.That.Has.Special-Chars`[but-no.spaces`]and.definitely.exists\"
PS C:\Users\Kenny> cd $filePath
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd $filePath
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
PS C:\Users\Kenny> cd 'C:\\Complicated.File.Path.That.Has.Special-Chars`[but-no.spaces`]and.definitely.exists\'
PS C:\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists> cd c:
PS C:\Users\Kenny> Write-Host $filePath
C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\
PS C:\Users\Kenny> cd "$filePath"
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd "$filePath"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
PS C:\Users\Kenny> cd ${filePath}
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd ${originalPath}
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
PS C:\Users\Kenny> cd ${$filePath}
cd : Cannot process argument because the value of argument "path" is null. Change the value of argument "path" to a
non-null value.
At line:1 char:1
+ cd ${$filePath}
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Location], PSArgumentNullException
+ FullyQualifiedErrorId : ArgumentNull,Microsoft.PowerShell.Commands.SetLocationCommand
PS C:\Users\Kenny> cd $($filePath)
cd : Cannot find path 'C:\\Complicated.File.Path.That.Has.Special-Chars[but-no.spaces]and.definitely.exists\' because it does not exist.
At line:1 char:1
+ cd $($filePath)
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\\Complicated...initely.exists\:String) [Set-Location], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
If I had a penny for every minute I've wasted on PowerShell's insistance that backticks, quotes and other meta-characters are just right, I would be the richest man on Earth! Somebody please save me from this madness!
And BTW, what I'm actually trying to do is recurse through a bunch of folders and delete everything that isn't a video file, like so...
Remove-Item -Path $filePath -Recurse -Exclude '*.avi','*.mkv','*.mp4'
...which doesn't work for (presumably) the same reason: not being able to pass a variable to the -Path parameter. And if someone is feeling really generous, they could also help me with this. MTIA! :D
Use -LiteralPath instead of -Path because some of the special characters where interpreted with -Path.
Remove-Item -LiteralPath
Special characters are just so much fun in PS right?
-LiteralPath works exactly like Patrick explained, but they don't allow for wildcards; because they're literal.
Have you tried using single quotes ' instead of double quotes ". This allows you to escape special characters, while still evaluating wildcards. Try the commands below:
New-Item -Path 'C:\Users\username\PSScripts\bracket`[\te$t.txt'
Get-Item -Path 'C:\Users\username\PSScripts\bracket`[\*'
Also, if it helps, I use VSCode for most scripting and, if you use tab completion, it will format this properly for you.
I hope that helps!
The solution to my overall problem ended up being this line of my batch script:
powershell -Command "Get-ChildItem -Recurse -LiteralPath %filePath% | Where-Object Extension -match '^(?!(\.avi|\.mkv|\.mp4)$)' | Remove-Item"
The regex was the hardest to get right, since I haven't used negative lookaheads before, but after ~2 hours of total time spent on this one line of code, it finally works!

Problems with whitespaces on Powershell

I have a Powershell script to remove items on a folder:
Get-ChildItem D:\FUNDACIÓN CB\Pedro Corchero Murga\Info de vídeos\Proyectos\* | Remove-Item -Recurse
The problem is that I'm having issues with the path because it have whitespaces and gives me this error:
Get-ChildItem : No se encuentra ningún parámetro de posición que acepte el argumento 'Corchero'.
En línea: 1 Carácter: 1
+ Get-ChildItem D:\FUNDACIÓN CB\Pedro Corchero Murga\Info de vídeos\Pro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
How I can fix it?
Simply add quotes " " to the path:
Get-ChildItem "D:\FUNDACION CB\........"

"Unknown Switch" error when using 7-zip in PowerShell script to archive file names that start with a `-`

I have a series of files in a folder that contain large log files
-20180907 1229 debug.log
-20180907 1229 system.log
I want to write a PowerShell script to archive them down in size. Here's my script:
dir *.log | % {
$archive = '"' + $_.Name + '.7z"'
$archive
$source = '"' + $_.Name + '"'
$source
&"C:\Program Files\7-Zip\7z.exe" -mx9 a -t7z $archive $source -WhatIf
}
When I run it, however, I get the following output:
"-20180907 1229 debug.log.7z"
"-20180907 1229 debug.log"
7z.exe :
At C:\Users\User\Temporary\Test 7z\archive-logs.ps1:6 char:5
+ &"C:\Program Files\7-Zip\7z.exe" -mx9 a -t7z $archive $source
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Command Line Error:
Unknown switch:
-20180907 1229 debug.log.7z
"-20180907 1229 system.log.7z"
"-20180907 1229 system.log"
7z.exe :
At C:\Users\User\Temporary\Test 7z\archive-logs.ps1:6 char:5
+ &"C:\Program Files\7-Zip\7z.exe" -mx9 a -t7z $archive $source
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Command Line Error:
Unknown switch:
-20180907 1229 system.log.7z
Even though I am wrapping the file name in double quotes it appears as 7-Zip is ignoring the double quotes.
Any ideas?
I tried this variant (wrapping the file names in single quotes):
dir *.log | % {
$archive = "'" + $_.Name + ".7z'"
$archive
$source = "'" + $_.Name + "'"
$source
&"C:\Program Files\7-Zip\7z.exe" -mx9 a -t7z $archive $source
}
And this time I got this output:
'-20180907 1229 debug.log.7z'
'-20180907 1229 debug.log'
7-Zip 18.05 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2018-04-30
Open archive: '-20180907 1229 debug.log.7z'
--
Path = '-20180907 1229 debug.log.7z'
Type = 7z
Physical Size = 32
Headers Size = 0
Solid = -
Blocks = 0
Scanning the drive:
7z.exe :
At C:\Users\User\Temporary\Test 7z\archive-logs-B.ps1:6 char:5
+ &"C:\Program Files\7-Zip\7z.exe" -mx9 a -t7z $archive $source
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
WARNING: The system cannot find the file specified.
'-20180907 1229 debug.log'
0 files, 0 bytes
Updating archive: '-20180907 1229 debug.log.7z'
Add new data to archive: 0 files, 0 bytes
Files read from disk: 0
Archive size: 32 bytes (1 KiB)
Scan WARNINGS for files and folders:
'-20180907 1229 debug.log' : The system cannot find the file specified.
----------------
Scan WARNINGS: 1
It's created files like '-20180907 1229 debug.log.7z', but with no content.
Try this:
$executable = "C:\Program Files\7-Zip\7z.exe"
dir *.log | % {
$archive = "$($_.Name).7z"
$archive
$source = $_.Name
$source
$oneliner = "a",".\$($archive)",".\$($source)", "-mx4"
& $executable #oneliner
}
I think it don't needs to be enclosed in quotes.
What if I do the following?
dir *.log | % { &"C:\Program Files\7-Zip\7z.exe" -mx9 a -t7z "$_.7z" $_ }

path not found?

I am trying to run the below against multilpe servers using Powershell 3.0 but for some reason I am getting back that the path does not exist...even though it does?
Any ideas?
CODE:
clear
$computer = Get-Content -path c:\temp\servers.txt
foreach ($computer1 in $computer){
Write-Host $computer1
Get-Content -Path '\\$computer1\C$\Program Files\BMC Software\BladeLogic\RSCD\rscd.log' -Tail 10
}
ERROR:
SV191267 Get-Content : Cannot find path '\$computer1\C$\Program
Files\BMC Software\BladeLogic\RSCD\rscd.log' because it does not
exist. At
C:\Users\gaachm5\AppData\Local\Temp\e4651274-dcab-4a87-95a6-0f11437a7187.ps1:7
char:1
+ Get-Content -Path '\$computer1\C$\Program Files\BMC Software\BladeLogic\RSCD\rs ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\$computer1\C$...c\RSCD\rscd.log:String) [Get-Content],
ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
SV193936 Get-Content : Cannot find path '\$computer1\C$\Program
Files\BMC Software\BladeLogic\RSCD\rscd.log' because it does not
exist. At
C:\Users\gaachm5\AppData\Local\Temp\e4651274-dcab-4a87-95a6-0f11437a7187.ps1:7
char:1
+ Get-Content -Path '\$computer1\C$\Program Files\BMC Software\BladeLogic\RSCD\rs ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\$computer1\C$...c\RSCD\rscd.log:String) [Get-Content],
ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
try:
"\\$computer1\C`$\Program Files\BMC Software\BladeLogic\RSCD\rscd.log" -Tail 10
In single quotes ' the variable are not expanded but treated as literal as $computer1, the $ for the $admin share must be escaped with a backtick `
The path that can't be found only has one \ on the front of it, a UNC share must begin with two \'s. I can see from your code it looks like you are prefixing the two \'s but it doesn't look like it's being carried over.
I would use double quotes instead of single quotes as already pointed out, if you do that then you should not need to escape the $ character either.
Assuming a file called file.txt exists in the C:\temp folder on the local machine.
This fails:
$computer1 = "localhost"
Test-Path '\\$computer1\c$\temp\file.txt'
This works:
$computer1 = "localhost"
Test-Path "\\$computer1\c$\Temp\file.txt"

Quote Madness in Powershell

I'm using invoke-expression in PowerShell to create an archive, but it's not working due to spaces in the exe path. These are my variables:
Set-Variable -name DIRRELEASE -value (Join-Path $env:UserProfile "\Documents\Coding\_Projects\ChickenPing\trunk\Dist\current\")
$srcPath = (Join-Path $DIRRELEASE ("myapp_1.90-src.zip"))
Set-Variable -name WinRarFilter -value "-x*\.svn -x*\.svn\* -x*\nutrition.db3"
Set-Variable -name WinRarOpts -value "-r -s -m5 -inul"
$WinRar = `"C:\Program Files\Winrar\winrar.exe`"
#Then using this to invoke:
Invoke-Expression ($WinRAR + " a " + $srcPath + " " + $WinRARFilter + " * " + $WinRAROpts)
When I run the script I get this error:
The term 'a' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try
again. At line:1 char:3
+ a <<<< C:\Users\Echilon\Documents\Coding_Projects\MyApp\trunk\Dist\c
urrent\myapp_1.95-src.zip -x*.svn -x*.svn* -x*\nutrition.db3 * -r
-s - m5 -inul
+ CategoryInfo : ObjectNotFound: (a:String) [], CommandNotFoundEx ception
+ FullyQualifiedErrorId : CommandNotFoundException
I just can't find the right combination of quotes and plusses.
You could make this a lot easier to work with by using the call operator &.
& $WinRAR a $srcPath "-x*\.svn" "-x*\.svn\*" "-x*\nutrition.db3" * -r -s -m5 -inul