I have a simple PowerShell script that using windows.forms for presenting and getting data using GUI.
It works when I run it using PowerShell , but doesn't work via CMD.
Here is the .ps1 example :
[System.Windows.MessageBox]::Show('message','Step 1','YesNoCancel','Question')
batch file for executing :
powershell "&{start-process powershell -ArgumentList ' -noprofile -file c:\temp\gui.ps1' -verb RunAs} exit $LASTEXITCODE" < NUL
Th error I get is : Unable to find type [System.Windows.MessageBox].
I understood that the CMD running with different context and the assembly need to be loaded , so I tried to load it from the CMD command , but still same error .
powershell "&{[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); start-process powershell -ArgumentList ' -noprofile -file c:\temp\gui.ps1' -verb RunAs} exit $LASTEXITCODE" < NUL
Error:
Any idea ?
You could try something like this:
PowerShell -NoProfile -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\temp\gui.ps1""' -Verb RunAs}"; Exit $LastExitCode
this is completely untested
OK I figure it out.
The issue was with the PowerShell script,
I used a [System.Windows.MessageBox] instead a [System.Windows.Forms.MessageBox]
Before:
[System.Windows.MessageBox]::Show('message','Step 1','YesNoCancel','Question')
After:
[System.Windows.Forms.MessageBox]::Show('message','Step 1','YesNoCancel','Question')
It works without changing the batch file.
Thanks,
Try running the following in the batch file:
powershell -command [System.Windows.Forms.MessageBox]::Show('message','Step 1','YesNoCancel','Question')
I hope this is helpful, if you have any other questions, please comment below.
Related
I have created a bat file that creates a csv file, please see below
#echo off
echo %date%,%time%,%computername%,%username% >> %random%.csv
This produces csv file which contains the following data:
29/05/2021,15:35:31.10,PC9083,fmartin
But I need the bat file to include these headers e.g Date,Time,Host,Name if possible e.g.
Date,Time,Host,Name
29/05/2021,15:35:31.10,PC9083,fmartin
Any ideas on how to accomplish this? any info would be greatly appreciated
Many Thanks
John
If you wanted to move ahead and use PowerShell, this would work. Using -UseQuotes AsNeeded requires PowerShell Core 7+. If you remove -UseQuotes AsNeeded it will work with Windows PowerShell 5.1, but every field will be quoted.
New-Object psobject -Property ([ordered]#{"Date"=(Get-Date).ToString('dd/MM/yyyy');
"Time"=(Get-Date).ToString('HH:mm:ss.ff');"Host"=$Env:COMPUTERNAME;"Name"=$Env:USERNAME}) |
Export-Csv -Path '.\so-createcsv.csv' -Encoding ascii -NoTypeInformation -UseQuotes AsNeeded
If you must keep the code in a cmd.exe batch file script, this could be used. Use pwsh.exe for PowerShell Core 6+. Use powershell.exe for Windows PowerShell 5 or earlier.
pwsh.exe -NoLogo -NoProfile -Command ^
"New-Object psobject -Property ([ordered]#{""Date""=(Get-Date).ToString('dd/MM/yyyy');""Time""=(Get-Date).ToString('HH:mm:ss.ff');""Host""=$Env:COMPUTERNAME;""Name""=$Env:USERNAME}) |" ^
"Export-Csv -Path '.\so-createcsv.csv' -Encoding ascii -NoTypeInformation -UseQuotes AsNeeded"
How do I have to escape the quotation marks in this batch code?
I have the following code:
echo ""powershell -Executionpolicy Bypass -Command "get-clipboard > C:\File.txt""" > C:\Helptool.cmd
This code should generate the file "Helptool.cmd". The content should be as follows:
powershell -Executionpolicy Bypass -Command "get-clipboard > C:\File.txt
Where do I have to put ^ characters in the first batch code?
When I run the above code, the contents of the newly created batch file are incorrectly as follows:
"" powershell -Executionpolicy Bypass -Command "get-clipboard> C: \ File.txt" ""
The two quotes at the beginning and the three quotes at the end are undesirable. I'll get rid of them by escaping. or? Just how do I go about this?
You do not need any carets, ^, if you doublequote the entire PowerShell -Command:
This version uses the backslash to escape the nested doublequotes:
#Echo #"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-Clipboard -Format Text -Raw -TextFormatType UnicodeText > \"C:\File.txt\"" > "C:\Helptool.cmd"
If you prefer to use singlequotes in PowerShell, there's nothing to escape:
#Echo #"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-Clipboard -Format Text -Raw -TextFormatType UnicodeText > 'C:\File.txt'" > "C:\Helptool.cmd"
Please note, that I have removed your -ExecutionPolicy parameter, as it is not needed for running -Commands, (only PowerShell -Files). The full path to, and extension for, the powershell executable, are optional, but recommended, as is the -NoProfile parameter. You should open a Windows PowerShell window, and read the output from Get-Help Get-Clipboard -Full, to find out what the -Format, Raw, and -TextFormatType parameters do.
I am trying to get SQL to execute some powershell commands using xp_cmdshell which has been working, however I'm running into an unusual problem. When I try to use a pipeline, it doesn't recognize the command after the pipeline. I tried this from the standard cmd line and can confirm that the same issue happens. This is the command I'm using:
powershell.exe -command get-eventlog -Newest 10 -LogName Application -Before "2018-04-18T22:02:23" -After "2018-04-17T22:02:23" -computername dk01sv1115 | Select Message
When I use the command without using | Select Message at the end, it works without issue. The issue is I'm not getting the full event message I've tried using Select and Format functions to try to get the full details but the pipe appears to be the issue. If you run the same command after starting powershell (IE run powershell.exe then run the command) it works without issue, however when you use SQL to run powershell.exe as a seperate line in SQL it runs indefinitely. EXAMPLE SQL:
Declare #command nvarchar(1000),#computername nvarchar(1000)
Set #computername = 'test'
Set #command = 'powershell.exe
get-eventlog -Newest 10 -LogName Application -Before "' + REPLACE(Convert(VARCHAR(255),GETDATE(),120),' ','T') +'" -After "' + REPLACE(Convert(varchar(255),DateAdd(dd,-1,GETDATE()),120),' ','T') + '" -computername ' + #computername + '
exit'
exec xp_cmdshell #command
The | Select Message part is interpreted by cmd.exe, not PowerShell, because the pipe symbol (|) is special in cmd.exe as well (with roughly the same meaning), and you haven't enclosed it in "...".
The best approach to calling PowerShell from cmd.exe is to pass the entire PowerShell command as a single, double-quoted string ("...") to the -Command parameter:
powershell.exe -command "get-eventlog -Newest 10 -LogName Application -Before 2018-04-18T22:02:23 -After 2018-04-17T22:02:23 -computername dk01sv1115 | Select Message"
Tips regarding embedded quoting:
To quote literals, you can use '...' inside the overall "..." string.
Note that the values that were quoted in your original command didn't actually need quoting (e.g., "2018-04-18T22:02:23"), so I used them unquoted in my reformulation.
If you need to embed " chars., use \" (sic - even though PowerShell-internally it is ` that serves as the escape character).
If you use the "PowerShell -command" form then place the complex command in quotes or curly braces.
Update:
Adding the ^ escape character works through Invoke-SQLCommand:
Invoke-Sqlcmd -ServerInstance ECS-DCTS05 -Database Test -Query "xp_cmdshell 'powershell -command dir c:\ ^| format-list'"
This works from various places starting cmd.exe:
powershell -noprofile -command "get-childitem | format-list" # quoted
This does NOT use the format-list:
powershell -noprofile -command get-childitem | format-list # no quotes/braces
ADDED:
Actually the following commands all work as expected on my Win7 PowerShell 5.1 machine:
Start search or WinKey+Run:
cmd /k powershell -noprofile -command "get-childitem | format-table"
OR from a cmd prompt that is open:
powershell -noprofile -command "get-childitem | format-list"
powershell -noprofile -command "get-childitem | format-table"
In each case the format command words as expected.
If you are having trouble with quoting then the CMD escape OUTSIDE of quotes is ^, so sometimes prefixing the pipe with ^ will help in Cmd.exe (e.g., in cmd.exe for /f ...in ("command here with ^| pipe") do ... statements.
So does:
powershell -noprofile -command "get-childitem | ForEach-Object FullName"
Which proves that PowerShell is running the 2nd element of the pipe.
EDITED: This also works but as a comment mentioned only from within PowerShell since CMD doesn't understand the curly braces:
powershell -noprofile -command { get-childitem | format-list } # curly braces added
i have a batch will with a small script as below. Now i want to modify it with RUNAS so that I can provide it a user without having the need to give him administrator password.
#ECHO OFF
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~xyz0.ps1""' -Verb RunAs}"
PAUSE
I added the RUNAS with a few parameters, as shown below, but it encounters an error:
ECHO OFF
runas /profile /user:Administrator /savecred "PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~xyz0.ps1""' -Verb RunAs}""
PAUSE
ERROR:
Attempting to start PowerShell.exe -NoProfile -Command as user
"ABC\Administrator" ... '{Start-Process' is not recognized as an
internal or external command, operable program or batch file. Press
any key to continue . . .
PS: without introducing RUNAS, the batch file runs just fine.
can anyone help, please.
The parameter value "/user:GLOBAL\svc-prodapp" is not accepted at this path.
Need help in understanding if there is any issue with the syntax.
Below is my BAT File code:
PowerShell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs /user:GLOBAL\svc-prodapp}"
sc \\ABCDEVSQL002 stop "MSSQLServerOLAPService"
sc \\ABCDEVSQL002 start "MSSQLServerOLAPService"
$timeoutSeconds = 240