I would like to execute a ping sweep, which is this powershell command:
$NET="192.168.111";for($i=1;$i -lt 255;$i++){$command="ping -n 1 -w 100 $NET.$i > nul 2>&1 && echo $NET.$i";start-process -nonewwindow "cmd" -argumentlist "/c $command" -redirectstandardoutput "tmp$i.txt"};cat tmp*.txt > sweep.txt
I need to do this inside cmd, I have already tried:
Wihout Quotes
powershell -c $NET="192.168.111";for($i=1;$i -lt 255;$i++){$command="ping -n 1 -w 100 $NET.$i > nul 2>&1 && echo $NET.$i";start-process -nonewwindow "cmd" -argumentlist "/c $command" -redirectstandardoutput "tmp$i.txt"};cat tmp*.txt > sweep.txt
With 1 doble quote
powershell -c "$NET="192.168.111";for($i=1;$i -lt 255;$i++){$command="ping -n 1 -w 100 $NET.$i > nul 2>&1 && echo $NET.$i";start-process -nonewwindow "cmd" -argumentlist "/c $command" -redirectstandardoutput "tmp$i.txt"};cat tmp*.txt > sweep.txt"
With 3 double quoutes
powershell -c """$NET="192.168.111";for($i=1;$i -lt 255;$i++){$command="ping -n 1 -w 100 $NET.$i > nul 2>&1 && echo $NET.$i";start-process -nonewwindow "cmd" -argumentlist "/c $command" -redirectstandardoutput "tmp$i.txt"};cat tmp*.txt > sweep.txt"""
Escaping the &&
powershell -c "$NET="192.168.111";for($i=1;$i -lt 255;$i++){$command="ping -n 1 -w 100 $NET.$i > nul 2>&1 \&\& echo $NET.$i";start-process -nonewwindow "cmd" -argumentlist "/c $command" -redirectstandardoutput "tmp$i.txt"};cat tmp*.txt > sweep.txt"
No success yet.
Thanks!
This worked for me, I used backticks before the quotes to escape. Even tho this could be accomplished with native Powershell commands but since you asked for something specific, here it is.
$NET="192.168.111"
for($i=1;$i -lt 255;$i++)
{
$command="echo ########### && echo Pinging $NET.$i && ping -n 1 -w 100 $NET.$i 2>&1"
start-process "cmd" -argumentlist "/c `"$command`"" -NoNewWindow -RedirectStandardOutput "tmp$i.txt"
}
while($true)
{
if(-not (Get-Process cmd -EA SilentlyContinue))
{
cat tmp*.txt > sweep.txt
break
}
sleep 5
}
Note that the while loop will wait for all cmd.exe processes to stop before breaking and unifying those files into sweep.txt. Remember to close any instance of cmd.exe you have opened before running this script or this loop will continue forever :D
Related
Why does Start-Process powershell.exe { Read-Host } work, but Start-Process pwsh.exe { Read-Host } does not?
I'm aware of the -ArgumentList switch of Start-Process, but it makes things more complicated when it comes to escaping quotation marks:
PowerShell 7.0.3 and 7.2.0-preview.3:
Start-Process pwsh.exe -ArgumentList '-Command "& {
''Hello World.''
Read-Host
}"' -Verb RunAs
PowerShell 5.1:
Start-Process powershell.exe {
'Hello World.'
Read-Host
} -Verb RunAs
On the other hand, when creating a new PowerShell session (without Start-Process), it is still possible to use a script block:
pwsh.exe {
'Hello World.'
Read-Host
}
Am I missing something here or is there a better/different approach which allows a script block to be executed parallel to the rest of a script?
pwsh get a filename by default in arguments.
If you try to run it in CMD you will see this:
CMD> pwsh { 'Hello!' }
The argument '{' is not recognized as the name of a script file. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Usage: pwsh[.exe] [-Login] [[-File] <filePath> [args]]
[-Command { - | <script-block> [-args <arg-array>]
| <string> [<CommandParameters>] } ]
(.. other help from pwsh ..)
It meant if you want to run some command you must write -Command { ... } in arguments.
But you can write more short command for run pwsh like this:
Start-Process pwsh.exe '-c', {
'Hello World.'
Read-Host
}
-c is shorter equivalent for -Command
Script block will converted to valid string in arguments
You don't show the error message. Pwsh defaults to -file while powershell defaults to -command. Running from cmd:
pwsh { 'hi there' }
The argument '{' is not recognized as the name of a script file. Check the spelling of
the name, or if a path was included, verify that the path is correct and try again.
pwsh -command { 'hi there' }
hi there
With start-process -nonewwindow you can see the error:
Start-Process -NoNewWindow pwsh.exe { Read-Host }
The argument 'Read-Host' is not recognized as the name of a script file. Check the
spelling of the name, or if a path was included, verify that the path is correct and try
again.
Usage: pwsh[.exe] [-Login] [[-File] <filePath> [args]]
[-Command { - | <script-block> [-args <arg-array>]
| <string> [<CommandParameters>] } ]
[-ConfigurationName <string>] [-CustomPipeName <string>]
[-EncodedCommand <Base64EncodedCommand>]
[-ExecutionPolicy <ExecutionPolicy>] [-InputFormat {Text | XML}]
[-Interactive] [-MTA] [-NoExit] [-NoLogo] [-NonInteractive] [-NoProfile]
[-OutputFormat {Text | XML}] [-SettingsFile <filePath>] [-SSHServerMode]
[-STA]
[-Version] [-WindowStyle <style>] [-WorkingDirectory <directoryPath>]
pwsh[.exe] -h | -Help | -? | /?
PowerShell Online Help https://aka.ms/powershell-docs
All parameters are case-insensitive.
"pwsh { 'hi there' } works within powershell. I'm not sure why.
.\echoargs { 'hi there' }
Arg 0 is <-encodedCommand>
Arg 1 is <IAAnAGgAaQAgAHQAaABlAHIAZQAnACAA>
Arg 2 is <-inputFormat>
Arg 3 is <xml>
Arg 4 is <-outputFormat>
Arg 5 is <text>
It seems to automatically run this?
pwsh -encodedCommand IAAnAGgAaQAgAHQAaABlAHIAZQAnACAA -inputFormat xml -outputFormat text
Here is a working example of sending a script block to new pwsh window with start-process (powershell 7)
while(1)
{
$script ={ write-host 'Hello World.'
pause
}
start-process -Filepath pwsh.exe -ArgumentList "-Command $script"
pause
}
This launches a ScriptBlock in a new window, which is from groser's comment
Start-Process pwsh.exe -ArgumentList "-c", {
'Hello World.'
Read-Host
}, "-noexit" -WindowStyle Maximized
The following launch's a script from an open PowerShell window
Start-Process pwsh.exe -ArgumentList "-c", ".\Child-Script.ps1", "-noexit" -WindowStyle Maximized
This launches a child .ps1 in the same directory as the parent .ps1 script in a new window
Parent-Script.ps1
Start-Process pwsh.exe -ArgumentList "-c", ("$PSScriptRoot\Child-Script.ps1"), "-noexit" -WindowStyle Maximized
I've read that you can pass arguments to a .msi file, but I have no idea how to do it correctly. I've tried the following, where $ArgumentList is an array.
$ArgumentList = #("/i .\NSClient v67.msi", "/norestart", "/quiet", "/l*v '$directory'", "token=$token", "host=$_host", "mode=$mode")
Start-Process "msiexec" -ArgumentList $ArgumentList -Wait -NoNewWindow
This is part of my script, where I'm trying to install NetSkope on my machine by executing a command.
In theory, the command should look like msiexec /i "NSClient v67.msi" token=loremipsum host=bryan.goskope.com mode=peruserconfig /norestart /quiet /l*v "C:\Temp\NetskopeInstallation.log.
#Find file path
$rawPath = Invoke-Expression -Command 'C:\Windows\System32\WHERE /r C:\Users\ /f NSClient*.msi'
#Extract the directory
$filePath = Invoke-Expression -Command "cmd.exe --% /c FOR /f ""tokens=1"" %A IN ($rawPath) DO (ECHO
'%~dpA')"
#Cast $filePath to work with string methods
$filePath = Out-String -InputObject $filePath
$filePath = $filePath.split("'")[1]
Invoke-Expression -Command "cmd.exe --% /c cd $filePath"
$ArgumentList = #("/i .\NSClient v67.msi", "/norestart", "/quiet", "/l*v '$directory'",
"token=$token", "host=$_host", "mode=$mode")
Start-Process "msiexec" -ArgumentList $ArgumentList -Wait -NoNewWindow
I would also recommend using the Powershell MSI Module
Concerning Start-Process:
-Argumentlist expects string as a type. I don't think you can just pass an array.
You also need to surround the parameters that require a space with escaped double quotes. The escape character is powershell is the grave-accent(`).
Another problem is that the variable $directory will never be expanded, because it is surrounded with single quotes. You need to remove those.
The following should work for your example, but I personally would just remove the space in the file name, since you don't need to do weird stuff with escaping.
Without escaping:
$ArgumentList = "/i .\NSClientv67.msi /norestart /quiet /l*v $directory token=$token host=$_host mode=$mode"
With escaping:
$ArgumentList = "/i `".\NSClient v67.msi`" /norestart /quiet /l*v $directory token=$token host=$_host mode=$mode"
Here's a slightly different syntax:
$MSIArguments = #(
"/x"
"`"C:\path with spaces\test.msi`""
"/qb"
"/norestart"
"/l*v"
"`"C:\path with spaces\test.log`""
)
Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow
I have been unable to understand why the following command don't trigger the silent installation of Power-Bi -
Start-Process msiexec -wait -ArgumentList '/i $ENV:Temp\PBIDesktop_x64.msi /qn /norestart ACCEPT_EULA=1'
where as the following works -
Start-Process msiexec -wait -ArgumentList '/i C:\Users\ADMINI~1\AppData\Local\Temp\PBIDesktop_x64.msi /qn /norestart ACCEPT_EULA=1
'
I am using an elevated ISE but the first command generates no errors and does nothing. I think that the $ENV:TEMP is not expanding. Please help.
regards,
Prateek
Powershell won't extend anything in a string if you're using single-quoted-ticks instead of double quotes. So change your code to:
Start-Process msiexec -wait -ArgumentList "/i $ENV:Temp\PBIDesktop_x64.msi /qn /norestart ACCEPT_EULA=1"
This link describes the quotation rules.
In short:
> $i = 1
> "Double quotes: $i + $i"
Double quotes: 1 + 1
> 'Single quotes: $i + $i'
Single quotes: $i + $i
Hope that helps
I'm executing the following 7 Zip command, which takes about 3-4 hours to finish, and then using $lastexitcode to make sure the compression was successful. Is this the right way of doing this? I'm finding the $lastexitcode not to always be 0 but the compressed file looks fine.
Could something else be modifying this exit code?
& $7z a -tzip -mx=1 $destinationdir\$today.zip $destinationdir\$db1 >$null 2>&1
if ($lastexitcode -ne 0){
...
The '>$null 2>&1' is just used so I don't see the output from 7 zip.
Thanks for any help.
I usually use another approach, like:
$process = Start-Process notepad.exe -PassThru -Wait
then use the
$process.ExitCode
Try this:
$process = Start-Process $7z -PassThru -Wait -ArgumentList "a -tzip -mx=1 $destinationdir\$today.zip $destinationdir\$db1 >$null 2>&1"
if ($process.ExitCode -ne 0) { ....}
I'm trying to enable-psremoting with PSexec on my servers with the following command:
psexec.exe \\server cmd /c "echo . | powershell (-verb runas -argumentlist (enable-psremoting -force))"
but it doesn't work. I'm guessing I'm messing up my double quotes. Any help?
Sune:)
Thanks for commenting all! I found out how to do it, and this is the completed code:
$user = "youruser"
$p = Read-Host "Enter domain password for $adminuser"
cls
$expression1 = "enable-psremoting -force"
$commandBytes1 = [System.Text.Encoding]::Unicode.GetBytes($expression1)
$encodedCommand1 = [Convert]::ToBase64String($commandBytes1)
$expression2 = "Set-ExecutionPolicy remotesigned -Force”
$commandBytes2 = [System.Text.Encoding]::Unicode.GetBytes($expression2)
$encodedCommand2 = [Convert]::ToBase64String($commandBytes2)
$expression3 = "Restart-Service winrm”
$commandBytes3 = [System.Text.Encoding]::Unicode.GetBytes($expression3)
$encodedCommand3 = [Convert]::ToBase64String($commandBytes3)
foreach ($server in (get-content c:\temp\enablepsremotinglist.txt))
{
echo " "
echo "Running on $server"
echo "--------------------------------------- "
echo " "
psexec.exe \\$server -h -u no\$user -p $p cmd /c "echo . | powershell -EncodedCommand $encodedCommand1"
psexec.exe \\$server -h -u no\$user -p $p cmd /c "echo . | powershell -EncodedCommand $encodedCommand2"
psexec.exe \\$server -h -u no\$user -p $p cmd /c "echo . | powershell -EncodedCommand $encodedCommand3"
}
I hope this can be of help to someone else one day:)
PS: Please keep in mind that this send your adminpassword as clear text..
It looks like you are trying to invoke PowerShell to run elevated. This might not be possible to do remotely... I was able to get this to work against a machine without UAC enabled (2003 server):
$c = Get-Credential
$u = $c.UserName
$p = $c.GetNetworkCredential().Password
$path = "C:\SysinternalsSuite"
& "$path\psexec.exe" \\server -u $u -p $p powershell.exe -Command "Enable-PSRemoting -Force"
For some reason though I had to press enter a couple times on the shell for it to keep spitting out output and eventually return me to a prompt. Not sure what's up with that...
You don't need PSExec for that. Check this script by PowerShell developer Lee.
http://poshcode.org/2141