Powershell ParentContainsErrorRecordException on shell namespace - shell

I'm trying to write an unzip powershell script, but I'm running into issues with the $shell.NameSpace() function.
function unzip ($sourceFile, $destination){
$shell = new-object -com shell.application
$zip = $shell.NameSpace($sourceFile)
foreach($item in $zip.items()){
$shell.Namespace($destination).copyhere($item) #Error here
}
}
unzip "$PWD\folder.zip" $PWD
When I run this, I get an error on the second $shell.NameSpace() call.
You cannot call a method on a null-valued expression.
At C:\scriptDir\unzipScript.ps1:9 char:6
+ $shell.NameSpace($destination).copyhere($item)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvokeMethodOnNull
What I dont understand is why this is failing on the second call. Clearly PWD exists and is a directory based on the first parameter.

Shell.NameSpace takes a string. $PWD is a PathInfo object. You can use $pwd.Path instead.
unzip "$PWD\folder.zip" $PWD.Path
As an alternative you can use the .Net System.IO.Compression.ZipFile class. Here is a sample.

Related

"Unable to find specified file" - Powershell

I wrote this function in my powershell profile:
function start {
if ($args[0] == "blender") {
Invoke-Item 'C:\Program Files\Blender Foundation\Blender 2.90\blender.exe'
}
}
It gives me the error below on line 1, at character 1:
Unable to find specified file
The file path is correct, since if I copy and paste the code Invoke-Item ... in my powershell it opens Blender normally. What can the problem be?
Thank you!
This happens, as your function name collides with Start-Process.:
get-alias -Name start
CommandType Name Version Source
----------- ---- ------- ------
Alias start -> Start-Process
Renaming the function is the first step for correction like so,
function start-myApps {
if ($args[0] == "MyApplication") {
Invoke-Item 'C:\Program Files\MyApplication\MyApplication.exe'
}
}
But that isn't enough, as it gives another an error:
Start-MyApps "MyApplication"
= : The term '=' 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:2 char:19
+ if ($args[0] == "MyApplication") {
+ ~
+ CategoryInfo : ObjectNotFound: (=:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CommandNotFoundException
This one is caused because Powershell's equality comparison operator is -eq, not ==.
The working version has different name and operator like so,
function start-myApps {
if ($args[0] -eq "MyApplication") {
Invoke-Item 'C:\Program Files\MyApplication\MyApplication.exe'
}
}

jq assignment where the path contain space

This might be a simple question but I am struggling to figure out how jq work with spaces in elements. (The following is in windows powershell)
PS C:\Users\Home> "{}" | jq ".mytest.path = """"success"""""
{
"mytest": {
"path": "success"
}
}
Now, I want to make "my test" two separate words. My desired output is
{
"my - test": {
"path": "success"
}
}
What query would I used? I tried the following:
PS C:\Users\Home> "{}" | jq ".""my - test"".path = """"success"""""
jq : jq: error: Could not open file test.path = "success": Invalid argument
At line:1 char:8
+ "{}" | jq ".""my - test"".path = """"success"""""
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (jq: error: Coul...nvalid argument:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
PS C:\Users\Home> "{}" | jq --raw-output ".""my test"".path = """"success"""""
jq : jq: error: Could not open file test.path = "success": Invalid argument
At line:1 char:8
+ "{}" | jq --raw-output ".""my test"".path = """"success"""""
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (jq: error: Coul...nvalid argument:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Any suggestions?
First, setting aside for the moment all the issues related to peculiarities of different shells, the jq filter you need is:
.["my test"].path = "success"
(If ever in doubt about using the .foo syntax, you can always fall back on the fundamental form: .["key name"].)
Since you are evidently conversant with the transmogrification required by the mighty PowerShell, I'll just point out here that one can simply place the jq program in a file (say program.jq) and invoke jq with the -f option (jq -f program.jq ...).

7Zip Powershell not working

I'm having trouble getting a .7z file to extract via Powershell.
My PowerShell function looks like this:
function unzip($file, $destination)
{
& 'C:\Program Files\7-Zip\7z.exe' x -y $file -o"$destination";
}
I get this error:
7z.exe :
At restoreQA.ps1:26 char:5
+ & 'C:\Program Files\7-Zip\7z.exe' x -y $file -o"$destination";
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Command Line Error:
Too short switch:
-o
There seems to be some sort of parsing error but I've tried every different combination to get it working.
Any ideas on why this is not working?
You need to put -o in quotes:
& 'C:\Program Files\7-Zip\7z.exe' x -y $file "-o$destination"

passing parameters from a windows batch script into a powershell script

I have a powershell script which uses 'quser' command to extract data regarding users logged onto a series of terminal servers.
I want to add a timestamp to the output files, this timestamp variable is created in a windows batch file which then calls the powershell script passes the computername and timestamp, but the powershell script is erroring with 'Missing ')' in function parameter list'
param(
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = 'localhost'
[string[]]$timestamp <========= this is the line I have added
)
If I remove my added line (marked in the code above), the script runs fine
You need to add a comma between the parameters:
param(
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = 'localhost',
[string[]]$timestamp
)
Also unless you want multiple timestamps you probably just want it to be a string rather than a string array (so [string]$timestamp).
The error message I get looks like this (except that it is in red). The first error points at the end of the localhost line then there is a knock-on error for what by that time seems to be a spurious ):
PS C:\> param(
>> [CmdletBinding()]
>> [Parameter(ValueFromPipeline=$true,
>> ValueFromPipelineByPropertyName=$true)]
>> [string[]]$ComputerName = 'localhost'
>> [string[]]$timestamp
>> )
>>
At line:5 char:38
+ [string[]]$ComputerName = 'localhost'
+ ~
Missing ')' in function parameter list.
At line:7 char:1
+ )
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInFunctionParameterList
I'm using Powershell 3 here. Other versions may show the error differently.

Multiple statements using && [duplicate]

This question already has answers here:
Can I get "&&" or "-and" to work in PowerShell?
(13 answers)
Closed 9 years ago.
What would be the equivalent statement of CMD's:
dir && cd ..
in Powershell?
I tried:
dir -and cd ..
but it throws error:
Get-ChildItem : A parameter cannot be found that matches parameter name
'and'.
At line:1 char:5
+ dir -and (cd ..)
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell
.Commands.GetChildItemCommand
There is not a direct equivalent in PowerShell of cmd.exe && which means "only execute right-hand side if the left-hand side succeeds." However you could write a short function to do the equivalent:
function IfTrue([ScriptBlock] $testExpression, [ScriptBlock] $runExpression) {
if ( & $testExpression ) { & $runExpression }
}
For example:
IfTrue { get-childitem "fileThatExists.txt" -ea SilentlyContinue } { "File exists..." }
If you want for the $testExpression to produce output, the IfTrue function can be written as follows:
function IfTrue([ScriptBlock] $testExpression, [ScriptBlock] $runExpression) {
& $testExpression
if ( $? ) { & $runExpression }
}
Bill
How about this?
dir; if ($?) {cd ..}
Running get-help about_automatic_variables | more explains:
$? Contains the execution status of the last operation. It contains
TRUE if the last operation succeeded and FALSE if it failed.
In PS, dir is just an alias for get-ChildItem; cd likewise for Set-Location.
edit: Same question here, including an answer straight from the horse's mouth.

Resources