I am extreme newbie to powershell. I have a script that I want to pass a URL as a parameter. The url runs a PHP process that creates and downloads a PDF file then the script prints the pdf and then deletes the pdf. I cannot get the URL parm to work.
Below is my script
$w=$args[0]
Start $w
$Directory = "C:\Users\pslessor\downloads\"
Get-ChildItem -path $Directory -recurse -include *.pdf | ForEach-Object {Start-Process -FilePath $_.fullname -Verb Print -PassThru | %{sleep 5;$_} | kill }
Remove-Item C:\Users\pslessor\downloads\* -include *.PDF
This script is being executed by a batch file PrintPl.bat
SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%PrintPl.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%' %1";
And I am testing with testprint.bat
C:\Wget\PrintPl "https://partners.wayfair.com/print_shipping_docs.php?Print=1&printPackingSlips=1&PackingSlipPOs=CS287851107"
The URL is all in one string this editor is forcing the line feed at .php?
The Error I am getting is
The string starting:
At Line:1 Char:25
+ & 'C:\Wget\Printpl.ps1' <<<< 'https://partners.wayfair.com/print_shipping_docs.php?print;
is missing the terminator: '.
At line:1 Char:85
+ & 'C:\Wget\PrintPl.psl' 'https://partners.wayfair.com/print_shipping_docs.php
?print; <<<<
+ CategoryInfo :ParserError: <https://partner...docs.php?print;:
String> [], ParentContainsErrorRecordException
+ FullyqualifiedErrorid : TerminatorExpectedAtEndOfString
'printPackingSlips' is not recognaized as internal or external command,
Operable program or batch file.
'PackingSlipPOs' is not recognized as an internal or external command,
operable program or batch File
This is happening because when you pass the arguments the command interpreter expands your variables and see this:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'C:\Wget\PrintPl.ps1' https://partners.wayfair.com/print_shipping_docs.php? Print=1&printPackingSlips=1&PackingSlipPOs=CS287851107"
So the command that it is trying to execute is C:\Wget\PrintPl.ps1, and it assumes that what comes next are arguments. Since what it is passed has a space, and is not enclosed in quotes or double quotes it assumes that it is multiple arguments. It sees it as:
Execute this script: C:\Wget\PrintPl.ps1
With the following arguments:
$Args[0]=?
$Args[1]=Print=1&printPackingSlips=1&PackingSlipPOs=CS287851107
To stop this from happening you will need to enclose the URL in quotes as well, so your command should look like this:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%' '%1'"
Edit: Ok, that didn't work for your case. So we're going to change this a little bit. Instead of -Command I'm going to suggest you use -File. So your Powershell execution line within the batch file will look like this:
PowerShell -NoProfile -ExecutionPolicy Bypass -File "%PowerShellScriptPath%" %*
You should be able to run the batch file exactly as you previously had been. I'm fairly confident that will work for you.
Related
In my DOCKERFILE I'm running some PowerShell script which creates a custom event log (on Windows Server), then writes an entry. [I should add that I'm currently doing this only for debug purposes.]
The script/command which creates the event log appear to execute without any problems, but an exception is thrown when writing to the log using...
RUN powershell.exe -command Write-EventLog -LogName "my_log_name" -Source "my_source" -Message "EventLog created by DOCKERFILE." -Category 0 -EventID 0 -EntryType Information
The following exception is thrown...
Write-EventLog : A positional parameter cannot be found that accepts argument
'created'.
At line:1 char:1
+ Write-EventLog -LogName my_log_name -Source my_source -EntryType Messag ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Write-EventLog], Parameter
BindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell
.Commands.WriteEventLogCommand
I also tried wrapping "EventLog created by DOCKERFILE." in parentheses but then it complained about the word by.
Why does it seem unable to parse "EventLog created by DOCKERFILE." as a string argument, but is instead parsing the words within the string?
UPDATE
Even if I wrap the command in double-quotes and the individual strings in single quotes, I get the same error.
UPDATE 2
Removing the quotes and escaping the spaces doesn't work either.
You need to use ` to escape the spaces:
RUN powershell.exe -command Write-EventLog -LogName my_log_name -Source my_source -Message EventLog` created` by` DOCKERFILE. -Category 0 -EventID 0 -EntryType Information
See: https://docs.docker.com/engine/reference/builder/#escape
This works for me from cmd (except for the unknown source). I'm not sure if docker has issues with single quotes. Double quotes are special in cmd. Note that new-winevent has replaced write-eventlog.
powershell write-eventLog my_log_name my_source 0 information 'EventLog created by DOCKERFILE.' -category 0
I'd like to set a file's name to a variable in a batch file. I'm already pulling the file name by pulling the total path length. Is there a way I can parse the path to only give me back the file name?
The particular script that I use to pull the path looks like this:
for /f "delims=_" %%J IN ('forfiles /p "%%F" /m *.extension /c "cmd /c echo #path"')
DO start "Program" /D "c:\fullpath" /Wait program -r %%J
Also, if there's an easier way to pull the file name and put it into a variable I'm open to that as well.
I am using following code to append ";C:\Python27" to environment variable PATH..
#echo off
Setx Path "%PATH%;C:\Python27" -M
PAUSE
but if i run this batch file more than once, it is appending ";C:\Python27" many times that should not happen.
SO i have to check for ;C:\Python27 before appending it to PATH variable.
Is there any command for this purpose?
The following Powershell should do it:
$needPython = $env:path | select-string -NotMatch -SimpleMatch "c:\python27"
if ($needPython) {
[Environment]::SetEnvironmentVariable("tstpath", $env:path + ";c:\python27", "User")
}
You can change User to Machine or Process to set a machine or process level environment variable.
You can run this directly from a powershell prompt.
If you're running this from a dos command line use (you need the full path to your script or .\ if it's in the current directory):
powershell "& '.\myscript.ps1'"
I am looking to execute a command in remote machine using invoke but the .cmd file will call for additional .vbs script. So i guess i may have to mention CScript if so how do i mention both cmd/c and cscript in the below command
Invoke-Command -computername blrscrv01 -ScriptBlock { param($path, $command ) cmd /c $path $command } -args '"C:\windows\system32\cscript.exe"','"/?"'
Your example worked for me when I removed the extra level of quoting.
Invoke-Command -computername blrscrv01 -ScriptBlock { param($path, $command ) cmd /c $path $command } -args 'C:\windows\system32\cscript.exe','/?'
Troubleshooting
Enter a remote session and poke around.
Enter-PSSession -computername blrscrv01
Verify that the target script exists and is accessible.
dir \\lcsap027\deploy\c2.cmd
dir \\lcsap027\deploy
type \\lcsap027\deploy\c2.cmd
Attempt to run the script interactively.
\\lcsap027\deploy\c2.cmd
or
cmd /c \\lcsap027\deploy\c2.cmd
Alternative
Another thing you might try is not invoking a cmd script remotely, but issuing the commands remotely. New-PSSession will return a handle you can use to deal interactively with the remote machine. You can repeatedly issue commands with Invoke-Command and get the results (as primitive data types and generic objects, though, not the actual objects themselves).
Altered Script
Here's an altered version of the script you put in your comment. I've removed the nested Invoke-Command (I don't know why it was necessary, you're already running commands on the remote machine). Since the line breaks got lost in the comment, I don't know if there were any statement separator problems (I'll just assume there weren't, though in its "formatted" form as a one-liner, it would have died horribly because PoSH wouldn't have known where one statement ended and the next began).
param(
[string]$ComputerName,
[string]$User,
[string]$pass
)
Get-PSSEssion | Remove-PSSession
$session = New-PSSession -ComputerName $ComputerName
Invoke-Command -Session $session -ScriptBlock {
param(
[string]$ComputerName,
[string]$Username,
[string]$Password
)
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive("x:", "\\machinename\sharename", $false, $Username, $Password)
cmd.exe /c "x:\c2.cmd"
$net.RemoveNetworkDrive("x:")
} -args $ComputerName, $User, $pass
This at least got the remote script to run and produced the expected output. (I emitted the computer name, user name, and file location.)
Bear in mind that this method doesn't employ any transport-/application-layer encryption, so the password is sent cleartext over the network.
I'm trying to figure out how to call a PowerShell script with spaces in the filename as a Delphi build event.
From CMD I have to call powershell.exe -Command "& 'Filename With Spaces.ps1'" which works fine.
Delphi on the other hand doubles the ampersand sign and is trying to turn the command into two commands.
I have tried to set this as the build event:
powershell.exe -Command "& '$(PROJECTDIR)\Prebuild.ps1' $(PROJECTDIR)"
What gets executed by MSBuild is:
powershell.exe -Command "&& 'D:\SVN\AccuLib 3.0\VCLUI\Prebuild.ps1' D:\SVN\AccuLib 3.0\VCLUI"
So what does it take to call a ps1 file containing spaces from a Delphi build event?
Try the File parameter instead, it doesnt require an ampersand:
powershell.exe -File "Filename With Spaces.ps1"
To use an ampersand sign you can create an intermediate cmd script.
Delphi build event:
Prebuild.cmd "$(PROJECTDIR)"
Prebuild.cmd file:
powershell.exe -Command "& 'Filename With Spaces.ps1'"