I have batch file which I usually execute from command line. Now I want add the following PowerShell command to the existing batch file. The PowerShell command is working fine when I execute from the PS terminal, but I'm having problem when I add to the batch file.
(Get-Content "C:\IN\mypath.txt" ) -Replace "\*ALTTIME\S* |\*ALTDATE\S* |\*CRTIME\S* |\*CRDATE\S* |\*IPPROCS\S* |\*OPPROCS\S*" | Set-Content "Out\mypath.txt"
This should work in your batch file:
powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypasss -Command "(Get-Content 'C:\IN\mypath.txt' ) -replace '\*ALTTIME\S* |\*ALTDATE\S* |\*CRTIME\S* |\*CRDATE\S* |\*IPPROCS\S* |\*OPPROCS\S*' | Set-Content 'Out\mypath.txt'"
Related
I want to run a script from commandline, which takes in a file directory as one of the parameters. The files are log files, which are postfixed by a date in following format: yyymmdd (Get-Date -Format filedate). I want to get the latest log file to be passed into the pwoershell script. e.g logfile-20210928.json
> e.g powershell.exe -NonInteractive -NoProfile -ExecutionPolicy
> RemoteSigned -File "D:\someapp\checkfile.ps1" -Path
> 'D:\logs\logfile-$(Get-Date -Format filedate).json'
I get the following error as powershell thinks -Format is a parameter.
A positional parameter cannot be found that accepts argument
'-Format'.
You are posting your 'Get-Date' part in single quotes, the variable is therefor plain text.
try:
"D:\logs\logfile-$(Get-Date -Format filedate).json"
Since you are using cmd to open the file you can not use powershell's Get-Date function in the commandline, you can try:
D:\logs\logfile-%date:~-4,4%%date:~-7,2%%date:~-10,2%.json
So the .bat file will be:
powershell.exe -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned -File "D:\someapp\checkfile.ps1" -Path "D:\logs\logfile-%date:~-4,4%%date:~-7,2%%date:~-10,2%.json"
And the powershell file will be:
param($path)
write-host $path
Output from cmd when running the .bat file:
D:\logs\logfile-20210928.json
You can run as command instead of file:
# checkfile.ps1
param($path)
"path is $path"
powershell .\checkfile logfile-$(Date -F filedate).json
path is logfile-20210928.json
I am trying to run the following PowerShell code via a CMD shell:
$logfile = "x:\test.log"
try {
get-service
Add-Content - Path $logfile -Value "It Worked"
} catch {
Add-Content -Path $logfile -Value $_.Exception.Message
}
From a CMD script I am calling the script as follows:
Powershell.exe -executionpolicy bypass -command "I paste the code above
here"
I have also tried it as follows:
Powershell.exe -executionpolicy bypass -command "& 'Command From Above'"
You can see from the error, it doesn't seem to be trying to run the entire command, because it seems to be trying to run my log command:
!https://imgur.com/y62FzB2
If I run something simple, it works without issue. As follows:
Powershell.exe -executionpolicy bypass -command "get-service"
As for what you tried:
When calling from cmd.exe, PowerShell code you pass to Windows PowerShell's CLI, powershell.exe (pwsh.exe for PowerShell Core) must be single-line:
Your screenshot suggests that you indeed used a single line, but you're missing ; chars. between your statements; these statement separators are needed whenever you want to place multiple statements on a single line.
Your next problem is related to passing the code as individual arguments to -command, to be pieced together by PowerShell before execution (as opposed to trying to pass a single argument with outer double-quoting).
In passing arguments individually, any enclosing "..." are stripped on parsing by PowerShell, so that "x:\test.log" turns into x:\test.log - no quotes - which caused the error you saw.
A solution:
By:
properly separating your statements with ;
escaping the " chars. in your command as \" (sic)
you can get your command to work:
powershell -c $logfile = \"x:\test.log\"; try { get-service; Add-Content -Path $logfile -Value \"It Worked\" } catch { Add-Content -Path $logfile -Value $_.Exception.Message }
Generally, however, note that if your code happens to contain characters (also) reserved in cmd.exe - notably & | < > % ^ - you would have to individually ^-escape them.
It's challenging to get quoting right on the command line, and ultimately the only robust solution - short of avoiding the problem by creating a (temporary) script file - is to use PowerShell's -EncodedCommand CLI parameter, which takes a Base64-encoded representation of the PowerShell code using the UTF-16LE character encoding.
Unfortunately, such a representation is not easy to come by in batch files.
I have always had trouble calling multi-line PowerShell scripts through cmd.
I have seen people convert their script into base64 and run that string from PowerShell but I can't remember how.
The easiest way would be to save your script as a .PS1 and run PowerShell -NoProfile -ExecutionPolicy Bypass -file "C:\ps.ps1"
Otherwise you could ECHO each line out to a .ps1 file and then run it. Would work as a .bat file.
#echo off
set WD=%~dp0
ECHO $logfile = "x:\test.log" >> "%WD%Script.ps1"
ECHO try { >> "%WD%Script.ps1"
ECHO get-service; >> "%WD%Script.ps1"
ECHO Add-Content - Path $logfile -Value "It Worked" >> "%WD%Script.ps1"
ECHO } catch { >> "%WD%Script.ps1"
ECHO Add-Content -Path $logfile -Value $_.Exception.Message >> "%WD%Script.ps1"
ECHO } >> "%WD%Script.ps1"
powershell.exe -ExecutionPolicy Bypass -File "%WD%Script.ps1"
del "%WD%Script.ps1"
I am trying to execute a very simple PowerShell script from Windows Scheduled Tasks.
My PowerShell script is this:
$currentTime = (Get-Date).ToString('yyyy-MM-ddTHH.mm.ss')
$contentToDump = "JLS"
$path = "$home\Desktop\resutfile_" + $currentTime + ".txt"
Add-Content $path $contentToDump
So it simply writes the string "JLS" to a file on my desktop with the current time as part of the name.
If I execute it using Windows PowerShell ISE it works fine. It also works fine when executing using the command prompt.
But when I hook up at Scheduled task it doesn't work. The task returns with a valid ("0x0")-result but no file is generated.
My configuration of the task is this:
Action: Start a program
Program/script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Add Arguments: -NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -Command “&{c:\Users\jls\desktop\untitled2.ps1}”
Start in (optional): C:\users\jls\desktop
The task is set to run as "me" with highest privileges and it is running locally on my machine where I am admin.
What am I missing?
You need to replace the -Command with -File in your Add Arguments
Add Arguments: -NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File c:\Users\jls\desktop\untitled2.ps1
If I have a powershell script the causes an error, I cannot get the error written to stderr if I use -noexit
For example if I have the following script foo.ps1
Get-Process none
If run this without -noexit the error is written to stderr
PS E:\Play>powershell -file .\foo.ps1 2>Error1.txt
If I use the -noexit param the error is not written to stderr
PS E:\Play>powershell -noexit -file .\foo.ps1 2>Error2.txt
What do I have to do to get the error written to stderr when using -noexit?
Why do you run powershell from PowerShell prompt? Just use
PS E:\Play>.\foo.ps1 2>Error1.txt
or (see Understanding Streams, Redirection, and Write-Host in PowerShell)
PS E:\Play>.\foo.ps1 *>&1 | Tee-Object -FilePath Error1.txt
To run above statements from cmd.exe command prompt, you need to escape some characters to be survived into the powershell (note all ^ carets):
E:\Play>powershell .\foo.ps1 2^>Error1.txt
or
E:\Play>powershell .\foo.ps1 *^>^&1 ^| Tee-Object -FilePath Error1.txt
Omit -file switch and use e.g. -NoExit from command prompt, see powershell /?.
Ok something so simple is just not working for me. I got a cmdlet that accepts a single parameter. I am trying to call a cmdlet within a Windows batch file. The batch file contains:
cd %SystemRoot%\system32\WindowsPowerShell\v1.0
powershell Set-ExecutionPolicy Unrestricted
powershell 'C:\convert-utf8-to-utf16.ps1 C:\test.txt'
powershell Set-ExecutionPolicy Restricted
pause
My ps1 file again not doing anything special:
function convert-utf8-to-utf16 {
$tempfile = "C:\temp.txt"
set-ExecutionPolicy Unrestricted
get-content -Path $args[0] -encoding utf8 | out-file $tempfile -encoding Unicode
set-ExecutionPolicy Restricted
}
When i execute the bat file it just runs to completion (no error messages) and it does not appear to create the temp.txt file.
I can run the powershell command file at the PS command prompt but not in cmd!
Anyone got any ideas what could be wrong?
Starting with Powershell version 2, you can run a Powershell script like so...
powershell -ExecutionPolicy RemoteSigned -File "C:\Path\Script.ps1" "Parameter with spaces" Parameter2
Now if I could only figure out a way to handle dragging and dropping files to a Powershell script.
I explain both why you would want to call a PowerShell script from a batch file and how to do it in my blog post here.
This is basically what you are looking for:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'C:\convert-utf8-to-utf16.ps1' 'C:\test.txt'"
And if you need to run your PowerShell script as an admin, use this:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\convert-utf8-to-utf16.ps1"" ""C:\test.txt""' -Verb RunAs}"
Rather than hard-coding the entire path to the PowerShell script though, I recommend placing the batch file and PowerShell script file in the same directory, as my blog post describes.
The problem is in the ps1 file - you declare a function but you don't call it.
I would modify it like this:
param($path)
function convert-utf8-to-utf16 {
$tempfile = "C:\temp.txt"
set-ExecutionPolicy Unrestricted
get-content -Path $args[0] -encoding utf8 | out-file $tempfile -encoding Unicode
set-ExecutionPolicy Restricted
}
convert-utf8-to-utf16 $path
it will work. However, it is not needed, you can simply ommit the function declaration and move the body into the script itself:
param($path)
$tempfile = "C:\temp.txt"
set-ExecutionPolicy Unrestricted
get-content -Path $path -encoding utf8 | out-file $tempfile -encoding Unicode
set-ExecutionPolicy Restricted
# Test-Args.ps1
param($first, $second)
write-host $first
write-host $second
Call from Command Prompt:
PowerShell.exe -NoProfile -Command "& {./Test-Args.ps1 'C:\Folder A\One' 'C:\Folder B\Two'}"
What's confusing is that if the script is in a folder path containing spaces, PowerShell doesn't recognize the script name in quotes:
PowerShell.exe -NoProfile -Command "& {'C:\Folder X\Test-Args.ps1' 'C:\Folder
A\One' 'C:\Folder B\Two'}"
But you can get around that using something like:
PowerShell.exe -NoProfile -Command "& {set-location 'C:\Folder X';./Test-Args.ps1 'C:\Folder
A\One' 'C:\Folder B\Two'}"
Don't use spaces in your .PS1 file name, or you're outta luck.
I got this working...The ps1 file does not need to be wrapped into a function. Just this declaration is ok.
$tempfile = "C:\temp.txt"
get-content -Path $args[0] -encoding utf8 | out-file $tempfile -encoding unicode
and the bat file calls it like:
cd %SystemRoot%\system32\WindowsPowerShell\v1.0
powershell Set-ExecutionPolicy Unrestricted
powershell "& 'C:\convert-utf8-to-utf16.ps1 C:\test.txt' 'C:\test.txt'"
powershell Set-ExecutionPolicy Restricted
pause
Try this syntax instead:
cd %SystemRoot%\system32\WindowsPowerShell\v1.0
powershell {Set-ExecutionPolicy Unrestricted}
powershell "& C:\convert-utf8-to-utf16.ps1 C:\test.txt"
powershell {Set-ExecutionPolicy Restricted}
pause