In Batch File, How to mask Input With asterisk * using Powershell? - 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.

Related

Running PowerShell Script in CMD (with popup window)

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

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

Grab an unknown IP from ipconfig and edit an unknown .ini line with that IP with BATCH script

Currently i have a setup where a program wants my LAN IP to attach their data to and this LAN IP are always random when i reboot my system. My LAN IP is always different as i do use a VPN so it's kind of a hazzle everytime i either change network or reboot as i do need to run the program, change it, restart it.
I do have a script that will make a variable with the correct IP, as it's always the first IPv4 Address. I did find it on this site.
set ip_address_string="IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set ip_address_string="IP Address"
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do (
echo Your IP Address is: %%f
goto :eof
)
This is golden, but every .ini edit post i've found do not actually work for me as it prints the line infinetly instead of editing the line.
As the size of the .ini is unknown i do need a powershell script in order for it to work as BATCH has limitations.
One user on Stackoverflow had this code:
(Get-Content C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini) | ForEach-Object { $_ -replace 'Default NAS Address=.*','Default NAS Address=BHPAPPDGN01V' } | Set-Content C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini
The line that needs to be changed is mostly random. Well, not random, but it'll move sometimes as users can make some changes and it'll push the IP line down or up depending on the settings.
I'm a bit novice when it comes to BATCH and powershell and i haven't figured out a way to transfer information to powershell. For example, BATCH will grab the IP, make a variable, run a powershell script editing the .ini. I do remember having a code that grabbed the IP to clipboard but i cannot find it in this moment.
My current progress is
#echo off
setlocal EnableExtensions
echo Exiting PROGRAM...
taskkill /IM PROGRAM.exe
timeout /t 1 /nobreak>nul
:check
for /F %%a in ('tasklist /NH /FI "IMAGENAME eq PROGRAM.exe"') do if %%a == PROGRAM.exe goto waiting
echo Restarting PROGRAM...
start "" "%ProgramFiles%\PROGRAM\PROGRAM.exe"
timeout /t 1 /nobreak>nul
exit
:waiting
echo PROGRAM is still running. Retrying...
timeout /t 3 /nobreak>nul
goto check
I don't need setlocal EnableExtensions but i did try to get it to work and it was needed then.
Currently the script look if the program is running, if it is, kill it softly (wait for it to natively quit) then restart it. My goal is to kill it softly, edit the .ini and then restarting it with the changed made.
A pure PowerShell solution would be most likely the best for this task because of Windows command processor cmd.exe is not designed for editing files.
But here is a pure batch file solution for determining the current IPv4 address and write it into the INIĀ file if it contains currently a different address.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IniFile=C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini"
if exist "%IniFile%" goto GetIpAddress
echo ERROR: File missing: "%IniFile%"
echo/
pause
goto EndBatch
:GetIpAddress
set "ip_address_string=IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set "ip_address_string=IP Address"
rem The string above must be IP-Adresse on a German Windows.
for /F "tokens=2 delims=:" %%I in ('%SystemRoot%\System32\ipconfig.exe ^| %SystemRoot%\System32\findstr.exe /C:"%ip_address_string%"') do set "IpAddress=%%I" & goto IpAddressFound
echo ERROR: Could not find %ip_address_string% in output of ipconfig.
echo/
pause
goto EndBatch
:IpAddressFound
set "IniEntry=Default NAS Address"
rem Remove leading (and also trailing) spaces/tabs.
for /F %%I in ("%IpAddress%") do set "IpAddress=%%I"
rem Do not modify the INI file if it contains already the current IP address.
%SystemRoot%\System32\findstr.exe /L /X /C:"%IniEntry%=%IpAddress%" "%IniFile%" >nul
if errorlevel 1 goto UpdateIniFile
echo The file "%IniFile%"
echo contains already the line: %IniEntry%=%IpAddress%
echo/
goto EndBatch
:UpdateIniFile
for %%I in ("%IniFile%") do set "TempFile=%%~dpnI.tmp"
(for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "%IniFile%" 2^>nul') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
set "Line=!Line:*:=!"
if not defined Line echo(
for /F delims^=^=^ eol^= %%J in ("!Line!") do (
set "FirstToken=%%J"
if "!FirstToken!" == "%IniEntry%" (
echo %IniEntry%=%IpAddress%
) else echo(!Line!
)
endlocal
))>"%TempFile%"
rem Replace the INI file by the temporary file, except the temporary file is empty.
if exist "%TempFile%" (
for %%I in ("%TempFile%") do if not %%~zI == 0 (
move /Y "%TempFile%" "%IniFile%" >nul
echo Updated the file "%IniFile%"
echo with the %ip_address_string% "%IpAddress%" for INI entry "%IniEntry%".
echo/
)
del "%TempFile%" 2>nul
)
:EndBatch
endlocal
Please read my answer on How to read and print contents of text file line by line?
It explains the awful slow code to update the INI file using just Windows Commands.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
ipconfig /?
move /?
pause /?
rem /?
set /?
setlocal /?
See also Single line with multiple commands using Windows batch file for an explanation of operator &.
Read the Microsoft article about Using command redirection operators for an explanation of >, 2>nul and |. The redirection operator | must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with ipconfig and findstr with using a separate command process started in background with %ComSpec% /c and the command line between the two ' appended.
Mofi had a great batch solution, but he mentioned that CMD was not really designed for file output like this. So here's a pure powershell solution that should do what you want. It does borrow a bit from the powershell snippet you included in your question.
$ip = Get-NetIPAddress -InterfaceAlias "Ethernet" #| Out-File PathTo:\net.ini
$content = get-content PathTo:\net.ini | ForEach-Object { $_ -replace "172.23.*","$($ip.IPAddress)"}
$content | Set-Content PathTo:\net.ini
Obviously this depends on you knowing the Interface Alias you want to grab, but you can find that easily with Get-NetIPAddress, and it shouldn't change. You'll also need to update the path information.

batch file that opens cmd prompt types string as command line

I got my batch file to open cmd prompt and change directory successfully, however what I cannot get to work is after the directory has changed I want the batch to then to enter a string as a command.
I've tried cmd /k string but that didn't seem to work, the cmd just sits at the changed directory. I've also tried:
set Opvar= echo string
%Opvar%
Again it just sits at the last changed directory. The batchisp line that's commented out is what the string is that I want to act as if I typed the whole string and pressed enter at the current directory prompt.
Here's the whole thing:
#Echo OFF
FOR /F "Tokens=*" %%# IN ('Reg Query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" ^| FIND "-1000"') DO (
FOR /F "Tokens=2,*" %%A IN ('Reg Query "%%#" /v "ProfileImagePath" ^| FIND /V "%%#"') DO (
set drive=%%B
Echo Admin SID: %%~n#
Echo Admin Folder: %%B
)
)
:Ask
echo What are you flashing? Please select one option(1,2, or 3):
echo 1. Main Board w/ 6-Station OpCon.
echo 2. Main Board w/ 12-Station Opcon.
echo 3. OpCon Board.
set /P INPUT=Type input: %=%
If "%INPUT%"=="1" goto Option1
If "%INPUT%"=="2" goto Option2
If "%INPUT%"=="3" goto Option3
::::::::::::
:Option1
echo Starting 6-Station DFU flash...
echo xcopy "%~dp0M1k_MainPCB\6-STATION\*.*" "%drive%\Desktop\MainPCB6\" /d /s /h /v /c /f /k /y
echo cmd /k "cd /d %drive%\Desktop\MainPCB6\6-STATION\Debug\"
goto End
::::::::::::
:Option2
echo Starting 12-Station DFU flash...
echo xcopy "%~dp0M1k_MainPCB\12-STATION\*.*" "%drive%\Desktop\MainPCB12\" /d /s /h /v /c /f /k /y
echo cmd /k "cd /d %drive%\Desktop\MainPCB12\12-STATION\Debug\"
goto End
::::::::::::
:Option3
echo Starting OpCon DFU flash...
xcopy "%~dp0M1k_SWPCB\SWPCB\*.*" "%drive%\Desktop\SWPCB\" /d /s /h /v /c /f /k /y
cmd /k "cd /d %drive%\Desktop\SWPCB\SWPCB\Debug\"
::batchisp -device at32uc3a0512 -hardware usb -operation erase f memory flash blankcheck loadbuffer SWPCB.elf program verify start reset 0
goto End
::::::::::::
:End
echo ******
echo *****
echo ****
echo ***
echo **
echo *
echo Flash Completed! Press any key to exit...
Pause>NUL&Exit
Any help would be much appreciated.
Thank you
You are changing the working directory in a new instance of CMD (CMD /K), use PUSHD to change the working directory in your current CMD instance and POPD to return to the last used directory:
#Echo OFF
PUSHD %WINDIR%"
Echo I'm on "%CD%" Directory!
POPD
Echo I'm on "%CD%" Directory!
Pause&Exit
Change your code to this:
:Option3
echo Starting OpCon DFU flash...
xcopy "%~dp0M1k_SWPCB\SWPCB\*.*" "%drive%\Desktop\SWPCB\" /d /s /h /v /c /f /k /y
PUSHD "%drive%\Desktop\SWPCB\SWPCB\Debug"
batchisp -device at32uc3a0512 -hardware usb -operation erase f memory flash blankcheck loadbuffer SWPCB.elf program verify start reset 0
POPD
goto :End
...Or if you want to start directly the command in a new instance of CMD change it to this:
CMD /k "Start /W """" "%drive%\Desktop\SWPCB\SWPCB\Debug\batchisp" -device at32uc3a0512 -hardware usb -operation erase f memory flash blankcheck loadbuffer SWPCB.elf program verify start reset 0"
PS: Remember that you don't need to change the working dir to start an app, you can write the path followed by the process name like in my last example.

Websphere bat files exits the batch file

I am writing scripts to automate the ear deployment to websphere and to create variables on the app.
My problem is that manageprofiles and startserver bat files exits my batch and to go to the next step I have to invoke it multiple times
Here is my script
FOR /F "tokens=*" %%i in ('type params.properties') do SET %%i
REM SET PATH=%PATH%;%AppServerPath%\bin
REM CALL setupCmdLine.bat -create -profileName %profile% -profilePath "%AppServerPath%\profiles\%profile%" -templatePath "%AppServerPath%\profileTemplates\default"
"%AppServerPath%\bin\manageprofiles" -listProfiles | findstr -i %profile% > nul:
if %ERRORLEVEL%==1 (
ECHO Creating profile %profile% on %AppServerPath%\profiles\%profile%
"%AppServerPath%\bin\manageprofiles" -create -profileName %profile% -profilePath "%AppServerPath%\profiles\%profile%" -templatePath "%AppServerPath%\profileTemplates\default"
)
ECHO Getting profile path
FOR /F "delims=" %%a IN ('manageprofiles -getPath -profileName %profile%') DO #SET PROFILEPATH=%%a
REM SET PATH=%OLD_PATH%;%PROFILEPATH%\bin
FOR /F "tokens=7 delims= " %%H IN ('serverStatus server1 ^| findstr "Application Server"') DO (
IF /I "%%H" NEQ "STARTED" (
v ECHO Starting server1
startServer server1
)
)
"%PROFILEPATH%\bin\wsadmin" -lang jython -f EEDeployer.jy "%PROFILEPATH%"
Any ideas or alternatives to check for a profile and create it if not exists then start server1 on it?
You need to CALL a batch to allow processing to return to the main batch.
If you simply execute a batch from within a batch, control is transferred, but no return is recorded.
CALL "%AppServerPath%\bin\manageprofiles" ...
should solve your problem. repeat with startserver...