Quote Madness in Powershell - 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

Related

running powershell command from batch fails but works in powershell

Im trying to run:
netsh lan show interfaces | findstr /i "GUID" > test.txt
set /p ethguid=<test.txt
echo %ethguid:~23%> test2.txt
set /p ethguidclean=<test2.txt
echo %ethguidclean%
powershell.exe -Command " Rename-Item "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{%ethguidclean%}" -NewName "11111111-1111-1111-1111-111111111111" "
pause
but i fails with error:
Rename-Item : A positional parameter cannot be found that accepts argument '8b384d18-7877-44ea-9b48-5f634a0ff1f6'.
At line:1 char:2
+ Rename-Item HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Rename-Item], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.RenameItemCommand
and if I run command directly in powershell it works! what am I doing wrong?
Change inside double quotes to single:
powershell.exe -Command " Rename-Item 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{%ethguidclean%}' -NewName '11111111-1111-1111-1111-111111111111' "

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!

Issue while executing simple PS script

PS C:> c:\test.ps1
Error:
*The term 'c:\test.ps1' is not recognized as the name of a
spelling of the name, or if a path was included, verify t
At line:1 char:12
+ c:\test.ps1 <<<<
+ CategoryInfo : ObjectNotFound: (c:\test.ps1
+ FullyQualifiedErrorId : CommandNotFoundException*
My Script contains
$letterArray = "a","b","c","d"
foreach ($letter in $letterArray)
{
Write-Host $letter
}
Move the script to another(deeper) folder and try again? You can also try
& c:\test.ps1

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"

Run tdpsql command from powershell

I have a script that requires 3 mandatory input parameters that will be used to run the backup command for tdpsql.
type (FULL, DIFF or LOG)
SQLServerinstancename
Database (SYSTEM, ALL, )
Within the powershell script I have the following line
$cmd = "C:\Progra~1\Tivoli\TSM\TDPSql\tdpsqlc.exe backup " + $idatabase + " " + $action + " " + $parameter + " /LOGFILE=" + $logdir + $logfile + "" $tdpsqlexe - The tdpsqlc exe.
$idatabase - Database name
$action = FULL\DIFF\LOG
$parameter = /sqlserver=TCP:" + $sqlserverinstance + " /SQLAUTH=INT /TSMOPTFile='" + $dsmoptfilename + "' /EXCLUDEDB=" + $exclude
& $cmd
When I echo the command it reports out what I use to run it using powershell command line but when I try to run it from Powershell with the & it fails with the following
The term
C:\Progra~1\Tivoli\TSM\TDPSql\tdpsqlc.exe
backup master FULL
/sqlserver=TCP:
/SQLAUT H=INT
/TSMOPTFile=C:\Progra~1\Tivoli\TSM\TDPSql\dsm.opt /EXCLUDEDB=tempdb /LOGFILE=<logfile>
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 TDPSQLBackup.ps1:166
char:6
+ & <<<< $cmd >> test2.txt
+ CategoryInfo : ObjectNotFound:
(C:\Progra~1\Tiv...forsqlimran.txt:String)
[], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Any help will be really appreciated.
You might try Invoke-Expression $cmd instead of & $cmd.
Yes better use Invoke-Expression, but if you still want to use & you can do it in this way.
$cmd = "C:\Windows\System32\notepad.exe"
$params = "C:\temp\file.txt"
& $cmd $params
Using a var for program file ans a var for parameters.
Instead of running a batch command you'd better try Powershell cmdlets as follow
import-module "C:\Program Files\Tivoli\Flashcopymanager\fmmodulemmc.dll"
import-module "C:\Program Files\Tivoli\Flashcopymanager\fmmoduleSQL.dll"
$startTime = get-date
Backup-DpSqlComponent -Name AdventureWorks2012 -BackupDestination TSM -BackupMethod Legacy -Full
$endTime = get-date
$activity = Get-FcmMmcActivity -StartTime $startTime -EndTime $endTime
$activity
Reference link
http://www-01.ibm.com/support/docview.wss?uid=swg21974345