Normally, PowerShell commands can be chained with semicolons. The following opens 2 notepads:
PS> notepad; notepad
You can also chain a more complex statement:
PS> Add-Type -AssemblyName System.IO.Compression; `
> $src = "C:\aFolder"; $zip="C:\my.zip"; `
> [io.compression.zipfile]::CreateFromDirectory($src, $zip)
Chained PowerShell commands can also be called from a CMD command-line:
C:\> powershell notepad; notepad
This post describes a method to create a .Net 4.0 PowerShell prompt, even if .Net 2.0 is the active framework on your OS. You create a .cmd script, and run that. Now you're in a .Net 4.0 environment.
Chaining also works at that 4.0 prompt:
C:\> ps4.cmd
PS> notepad; notepad
And also works from standard CMD prompt:
C:\> ps4 notepad; notepad
This post describes a way to do Add-Type
to an explicit pathname (needed to reference 4.0 assemblies from the ps4 prompt):
Add-Type -Path "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.IO.Compression.FileSystem\v4.0_4.0.0.0__b77a5c561934e089\System.IO.Compression.FileSystem.dll"
That works, even when chained at the ps4 prompt:
C:\> ps4
PS> Add-Type -Path "C:\x\System.IO.Compression.FileSystem.dll"; `
> $src = "C:\x\xl"; $zip="C:\x\xl.zip"; `
> [io.compression.zipfile]::CreateFromDirectory($src, $zip)
Problem: chaining the above statement fails when ps4 is launched at a standard command prompt (error in full at bottom of post):
C:\> ps4 Add-Type -Path "C:\x\System.IO.Compression.FileSystem.dll"; $src = "C:\x\xl"; $zip="C:\x\xl.zip"; [io.compression.zipfile]::CreateFromDirectory($src, $zip)
Yet, all the above methods work. Why? How can I make this work?
The term 'C:\x\xl' 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:73 + Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll; $src = C:\x\xl <<<< ; $zip=C:\x\xl.zip; [io.compression.zipfile]::CreateFromDirectory($src, $zip) + CategoryInfo : ObjectNotFound: (C:\x\xl:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException The term 'C:\x\xl.zip' 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:91 + Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll; $src = C:\x\xl; $zip=C:\x\xl.zip <<<< ; [io.compression.zipfile]::CreateFromDirectory($src, $zip) + CategoryInfo : ObjectNotFound: (C:\x\xl.zip:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException Exception calling "CreateFromDirectory" with "2" argument(s): "The path is not of a legal form." At line:1 char:138 + Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll; $src = C:\x\xl; $zip=C:\x\xl.zip; [io.compression.zipfile]::CreateFromDirectory <<<< ($src, $zip) + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException
The double quotes around the strings are removed when the daisy-chained commands are passed to powershell.exe
. Add-Type
isn't affected by this, since the path doesn't contain spaces, so it doesn't require quotes:
Add-Type -Path C:\x\System.IO.Compression.FileSystem.dll # <- this works
However, in an assignment operation PowerShell requires strings to be in quotes, otherwise it will interpret the string as a command and try to execute it:
$src = C:\x\xl # <- this would try to run a (non-existent) command 'C:\x\xl'
# and assign its output to the variable instead of assigning
# the string "C:\x\xl" to the variable
That is what causes the first two errors you observed. The third error is a subsequent fault, because the two path variables weren't properly initialized.
You should be able to avoid this behavior by escaping the double quotes:
ps4 Add-Type -Path \"C:\x\System.IO.Compression.FileSystem.dll\"; $src = \"C:\x\xl\"; $zip=\"C:\x\xl.zip\"; [io.compression.zipfile]::CreateFromDirectory($src, $zip)
or by replacing them with single quotes (because the latter are not recognized by CMD as quoting characters and are thus passed as-is to PowerShell, which does recognize them as quoting characters):
ps4 Add-Type -Path 'C:\x\System.IO.Compression.FileSystem.dll'; $src = 'C:\x\xl'; $zip='C:\x\xl.zip'; [io.compression.zipfile]::CreateFromDirectory($src, $zip)
However, rather than working around this issue I'd recommend creating and running proper PowerShell scripts, so you can avoid this problem entirely:
#requires -version 4
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$Path,
[Parameter(Mandatory=$true)]
[string]$Zipfile,
)
Add-Type -Assembly 'System.IO.Compression.FileSystem' | Out-Null
[IO.Compression.ZipFile]::CreateFromDirectory($Path, $Zipfile)
The script would be run like this:
powershell.exe -File zip.ps1 -Path "C:\x\xl" -Zipfile "C:\x\xl.zip"
If you change the execution policy to RemoteSigned
or Unrestricted
and also change the default handler for .ps1 files you could even run the script like this:
zip.ps1 -Path "C:\x\xl" -Zipfile "C:\x\xl.zip"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.