Running PowerShell Script in CMD (with popup window) - powershell

Hi I normally just right click and edit my scripts, then just run them through PowerShell ISE using the green arrow.
But I have a need to start /wait a script in a batch file. I want my script to run and then have the rest of the batch file to wait till the PowerShell script is closed. (Hence the start /wait)
And it works fine, but my issue is this:
it opens up fine but no matter if I choose the letters by the options or the numbers I set in the choice script it will either restart or close out depending on the choice.
**I had nice pictures to go with this but I don't have enough rep so here is a bit of code :(
powershell.exe Set-ExecutionPolicy -ExecutionPolicy Bypass
#Main Choice Script
$IP = New-Object System.Management.Automation.Host.ChoiceDescription '&Edit IP', 'Change IP
Address'
$Intro= New-Object System.Management.Automation.Host.ChoiceDescription '&Change Introscreen',
'Change Introscreen'
$Gecko = New-Object System.Management.Automation.Host.ChoiceDescription '&Replace Gecko',
'Change Gecko Folder'
$PCName = New-Object System.Management.Automation.Host.ChoiceDescription '&Host Name', 'Fix
Host Name'
$Firewall = New-Object System.Management.Automation.Host.ChoiceDescription '&Firewall
Settings', 'Fix Firewall Setting'
$Close = New-Object System.Management.Automation.Host.ChoiceDescription '&Close', 'Exit'
$options = [System.Management.Automation.Host.ChoiceDescription[]]
($IP,$Intro,$Gecko,$PCName,$Firewall,$Close)
$title = 'IT Tool'
$message = 'What do you want to do?'
$result = $host.ui.PromptForChoice($title, $message, $options,-1)
switch ('$result')
{
0 { "IP" }
1 { "Intro" }
2 { "Gecko" }
3 { "PCName" }
4 { "Firewall" }
5 { "Close" }
}
I cant seem to get the options to function right, I'm thinking:
CMD is too basic to open a prompt for choice window.
My code isn't setup to run outside ISE
** I'm fine that the cmd window is just text and not a popup, I just would like it to work.
Any help or tips would be appreciated.

As you mentioned you are willing to use batch-file I decided to post an option.
If your options are single commands per entry (or if you are willing to chain commands) you can preset the commands and use choice to select the option.
Note! Here I added some dummy commands to demonstrate how it works:
#echo off & cls
setlocal enabledelayedexpansion
set "sel="Edit IP","Change Introscreen","Replace Gecko",Hostname,Firewall,Close"
set "opt_1=ping localhost"
set "opt_2=echo something"
set "opt_3=echo Replace command here"
set "opt_4=hostname"
set "opt_5=echo firewall command here"
set "opt_6=exit /b"
:menu
set cnt=
for %%i in (%sel%) do (
set /a cnt+=1
echo !cnt!^) %%~i
set "_opt!cnt!=%%~i"
)
for /l %%c in (1,1,%cnt%) do set ch=!ch!%%c
choice /C %ch% /M "Enter Selection:"
echo You chose !_opt%errorlevel%!
!opt_%errorlevel%!
pause
set ch= & cls & goto :menu

You could of course just use a plain text menu directly in your batch file, by using the built-in choice.exe utility.
#Echo Off
:Menu
ClS
Echo 1. Edit IP
Echo 2. Change Introscreen
Echo 3. Replace Gecko
Echo 4. Host Name
Echo 5. Firewall
Echo 6. Close
%SystemRoot%\System32\choice.exe /C 123456 /M "What do you want to do"
GoTo Item%ERRORLEVEL%
:Item1
Echo Changing IP Address
%SystemRoot%\System32\timeout.exe /T 2 1>NUL
GoTo :Menu
:Item2
Echo Changing Introscreen
%SystemRoot%\System32\timeout.exe /T 2 1>NUL
GoTo :Menu
:Item3
Echo Changing Gecko Folder
%SystemRoot%\System32\timeout.exe /T 2 1>NUL
GoTo :Menu
:Item4
Echo Fixing Host Name
%SystemRoot%\System32\timeout.exe /T 2 1>NUL
GoTo :Menu
:Item5
Echo Fixing Firewall Setting
%SystemRoot%\System32\timeout.exe /T 2 1>NUL
GoTo :Menu
:Item6
Echo Exiting
%SystemRoot%\System32\timeout.exe /T 2 1>NUL
Exit /B

Related

windows 7 cmd hide fullscreen window

I have a cmd countdown script that minimize all windows, but not a fullscreen window (VLC media player). Is it possible to minimize / hide also the fullscreen window?
countdown.cmd
#echo off
set /p countdownminutes="Minutes: "
set /a countdownseconds = countdownminutes * 60
echo COUNTDOWN
echo %countdownminutes% Minutes
timeout /T %countdownseconds% /nobreak
powershell -command "(new-object -com shell.application).minimizeall()"
Please no solutions with third party software.
You could change that last phrase, since this should be the equivalent of minimise all windows. However, in comments you say it is not enough to deactivate VLC in full screen, so I have added that step before your minimizeall.
#echo off
set /p countdownminutes="Minutes: "
set /a countdownseconds = countdownminutes * 60
echo COUNTDOWN
echo %countdownminutes% Minutes
timeout /T %countdownseconds% /nobreak
mshta.exe vbscript:Execute("CreateObject(""SAPI.SpVoice"").Speak(""Minimising"")(window.close)")
mshta.exe vbScript:Execute("CreateObject(""WScript.Shell"").AppActivate(""VLC media player"", 0)(window.close)")
mshta.exe vbScript:Execute("CreateObject(""WScript.Shell"").SendKeys(""{F11}"")(window.close)")
powershell -command "(new-object -com shell.application).minimizeall()"
rem powershell -command "(New-Object -ComObject shell.application).toggleDesktop()"

Getting a variable from a powershell script, in a batch file

I have seen some similar questions on this here on stack overflow, but I cannot get any of the answers to far to work.
I have this .ps1 file that mounts a drive and echos the drive letter (expected $driverLetter = "G" || "H" || "I"):
$mountDisk = Mount-DiskImage -ImagePath $args[0] -Passthru
$driveLetter = ($mountDisk | Get-Volume).DriveLetter
echo $driveLetter
I'm running it from this batch file:
FOR /F "usebackq delims=" %%i IN (`powershell -File ./mountDisk.ps1 "%1"`) DO SET "d=%%i"
Echo %d%
Each time I get an empty variable. I've tried setting environment variables, but yield same result.
Here's how I'd probably do it, assuming that the initial path passed to the batch file is double-quoted as necessary.
#Echo Off & SetLocal EnableExtensions & Set "ISODrv="
If /I Not "%~x1" == ".iso" (Exit /B 1) Else For %%G In ("%~1") Do If "%%~aG" GEq "d" Exit /B 2
For /F %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Mount-DiskImage -ImagePath \"%~1\" -PassThru | Get-Volume).Driveletter" 2^>NUL') Do Set "ISODrv=%%G"
If Not Defined ISODrv (Exit /B 3) Else Echo %ISODrv%
Doing it this way eliminates the need for pre-creating a PowerShell script, and then any subsequent modifications to the execution policy. It only proceeds with the image mount if the received input value was an existing ISO file too. If you're running this batch file from a process which retrieves its exit code, 1 means that the input did not end with the case insensitive string .iso, 2 would mean that the input did end with the case insensitive string .iso, but it was a directory, not a file, and 3 would indicate that there was an error returning the mounted ISO image drive letter.
Try the following to run the cmd from the PowerShell and pathing their variables to it
# The command to pass to cmd.exe /cript
$var = "echo hello world & ping $ip & pause"
$ip = "192.168.1.1"
$var2 = "ping $ip & pause"
# Start the process asynchronously, in a new window,
# as the current user with elevation (administrative rights).
# Note the need to pass the arguments to cmd.exe as an *array*.
Start-Process -Verb RunAs cmd.exe -Args '/c', $var2, $var

Powershell - get console output into variable (not stdout, not stderror)

I have the exe from Lenovo that only provides command line output when run from a cmd window but not from PowerShell. The output seems to come from a ghost source other than StdOut or StdErr.
https://download.lenovo.com/pccbbs/mobiles/n2hgc06w.exe (you have to run and click install but all that does is unzip to c:\drivers\win\touchpadfw). Be sure to cancel the install prompt after extract.
This command gives me output to the console
& cmd.exe /c c:\drivers\win\touchpadfw\touchpadfw_aug2019\synreflash.exe /v /S 2
This also gives me output the the console and nothing in the variable
$var = (& cmd.exe /c c:\drivers\win\touchpadfw\touchpadfw_aug2019\synreflash.exe /v /S 2) 2>&1
Same here
$var = (& cmd.exe /c c:\drivers\win\touchpadfw\touchpadfw_aug2019\synreflash.exe /v /S 2 2>&1)
I feel like this exe is outputting in some other way than StdOut and StdErr but I don't know what. Nothing I've tried can capture what it is outputting. Is there a third method of output?
This is where it gets weird. Using "start cmd" to open a cmd window from the admin PowerShell, I run the exe directly in the cmd window but the output goes to the parent powershell console. I cannot get any output if I start the cmd window as admin directly.
Look at the SynReflash usage below you will notice that you would need to pass the last arg as /S 3 explicitly, to print to Standard Output as opposed to /S 2 is a silent mode
$cmdOutput = cmd.exe /c "C:\DRIVERS\WIN\TouchpadFW\n2hgc06w\synreflash.exe" /v /S 3 '2>&1'
OR
proc = [System.Diagnostics.Process]::Start([System.Diagnostics.ProcessStartInfo]#
{
'FileName' = "cmd.exe"
'Arguments' = "/C " + """C:\DRIVERS\WIN\TouchpadFW\n2hgc06w\synreflash.exe"" /v /s 3"
'CreateNoWindow' = $true
'UseShellExecute' = $false
'RedirectStandardOutput' = $true # to get stdout to $proc.StandardOutput
'RedirectStandardError' = $true # to get stderr to $proc.StandardError
})
$output = $proc.StandardOutput
$error1 = $proc.StandardError
write-host $output.ReadToEnd()
Output
FW Version: 1.2

In Batch File, How to mask Input With asterisk * using Powershell?

cls
#ECHO OFF
title Folder Secure
if EXIST "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}" goto UNLOCK
if NOT EXIST Secure goto MDLOCKER
:CONFIRM
echo (Y/N)
set/p "cho=>"
if %cho%==Y goto LOCK
if %cho%==y goto LOCK
if %cho%==n goto END
if %cho%==N goto END
echo Invalid choice.
goto CONFIRM
:LOCK
ren Secure "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}"
attrib +h +s "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}"
echo Folder locked
goto End
:UNLOCK
set/p "variable=>"
if NOT %variable%== (Here is Enter Your Password) goto FAIL
attrib -h -s "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}"
ren "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}" Secure
echo Folder Unlocked successfully
goto End
:FAIL
echo Invalid password
goto end
:MDLOCKER
md Secure
echo Secure created successfully
goto End
:End
Here is my Echo Code, Which is work for to hide the folder with command, y/n and unhide using password. it is work properly there is no mistake in my opinion.
But the problem is that, i need batch file to mask the input text with *.
and I found it on:
batch file to mask input with * without an external file
Here is a way to do it using Powershell in a batch file by Matt Williamson
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%pass
After this Wonderful solution which is works Great to mask my text.
but After some Modification, i can't understand where to put my Password?
Someone help me!! where do i put my password in Batch file?
Here is the Final Code:
cls
#ECHO OFF
title Folder Secure
if EXIST "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}" goto UNLOCK
if NOT EXIST Secure goto MDLOCKER
:CONFIRM
echo (Y/N)
set/p "cho=>"
if %cho%==Y goto LOCK
if %cho%==y goto LOCK
if %cho%==n goto END
if %cho%==N goto END
echo Invalid choice.
goto CONFIRM
:LOCK
ren Secure "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}"
attrib +h +s "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}"
echo Folder locked
goto End
:UNLOCK
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%pass
if NOT %pass%== folder goto FAIL
attrib -h -s "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}"
ren "Control Panel.{21EC2020-3AEA-1069-A2DD-08002B30309D}" Secure
echo Folder Unlocked successfully
goto End
:FAIL
echo Invalid password
goto end
:MDLOCKER
md Secure
echo Secure created successfully
goto End
:End
But it is not accepted my password.
I don't have a knowledge of Powershell!
You have to use %%p because you are storing it there. Secondly you are not at all providing any security like that. In corresponding Powershell You can use the below code under Powershell section which will help you to encrypt with your own key and you can decrypt it as well.
Instead of:
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%pass
Use should do this:
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p
Powershell :
The link is having the example where I have used an encrypted password based on AES. You can incorporate the same in your code.
## For the current user , it can encrypt and decrypt as well
$username = "user1#domain.com"
$pwdTxt = Get-Content $SecurePwdFilePath ;
$securePwd = $pwdTxt | ConvertTo-SecureString ;
$credObject = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $securePwd ;
# You can use the $credObject anywhere in your script now.
Hope it Helps you in understanding.

Powershell v2 - Installing Printer

I'm trying to automate printer installation on windows 7 x64, by using Powershell script. So far I have a script that successfully creates TCP/IP port but gives me an error - The arguments are invalid, when it executes printer installation part of the code. Any ideas on how to fix the problem and successfully install a printer through the Powershell? The code is as follows:
$hostAddress = "172.16.2.24"
$portNumber = "9100"
$computer = $env:COMPUTERNAME
$wmi= [wmiclass]"\\$computer\root\cimv2:win32_tcpipPrinterPort"
#$wmi.psbase.scope.options.enablePrivileges = $true
$newPort = $wmi.createInstance()
$newPort.hostAddress = $hostAddress
$newPort.name = "IP_" + $hostAddress
$newPort.portNumber = $portNumber
$newPort.SNMPEnabled = $false
$newPort.Protocol = 1
$newPort.put()
CMD.EXE /C "printui.exe /if /b "Test Printer" /f C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf /r "IP_172.16.2.24" /m "HP Laser Jet P3015""
Question Update: This is the working CMD code, so how do I incorporate it into the Powershell code above ?
printui.exe /if /b "HP Universal Printing PCL 6" /f "C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf" /u /r "IP_172.16.2.24" /m "HP Universal Printing PCL 6"
To embed double-quotes within a double-quoted string you need to escape them. Since you are not using variables, it is easier to use a single quoted string e.g.:
CMD.EXE /C 'printui.exe /if /b "Test Printer" /f C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf /r "IP_172.16.2.24" /m "HP Laser Jet P3015"'
If you ever need to use PowerShell variables inside this string, then you will need to switch back to double quotes and escape the necessary DQ characters e.g:
CMD.EXE /C "printui.exe /if /b `"$PrinterName`" /f C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf /r `"IP_172.16.2.24`" /m `"HP Laser Jet P3015`""
Sorry, but im not sure why you are calling CMD /C #PARAMS. I am just calling the printui.exe directly and it is working, and I only double quote the Args
# Printer Info, I keep this in an SQL DB, and return these values with a query:
$printerID = "<PrinterNameOrID>"
$printerIP = "<PrinterIP>"
$printerPort = "IP_$printerIP"
$printerModel = "<PrinterModelFromINF>"
$driverINFPath = "<UNCPathToDriverINF>"
# Build a new Local TCP Printer Port, naming it with values unique to the Printer ID:
$newPort = ([wmiclass]"Win32_TcpIpPrinterPort").CreateInstance()
$newPort.HostAddress = $printerIP
$newPort.Name = $printerPort
$newPort.PortNumber = "9100"
$newPort.Protocol = 1
$newPort.Put()
# Add the printer
printui.exe /if /b "$printerID" /f "$driverINFPath" /u /r "$printerPort" /m "$printerModel"
I know this has already been answered but you could borrow the code I have in this Excel Workbook (there is a link in the article). I realize it uses VBS but these are built in scripts in Windows and cutting / pasting into Excel has saved me many times and I've installed thousands of printers this way
best-tool-for-printer-creation-excel-vs-print-management-console
Try this:
runas /user:Contoso.com\user1 "printui.exe /if /b \"Test Printer\" /f \"C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf\" /r \"IP_172.16.2.24\" /m \"HP Laser Jet P3015\""