I'm writing a powershell script which calls an exe using the input parameters. This is my code:
param([string]$sourceIP, [string]$destinationIP, [string]$prefix)
$ErrorActionPreference = "Stop"
try
{
Write-Host "Starting Copy of Keyspaces to Dev"
Write-Host "Copying One"
.\CopyDatabase.exe -s $sourceIP -o $($prefix)_one -d $destinationIP -n $($prefix)_one -c
Start-Sleep -s 2
Write-Host "Copying Two"
.\CopyDatabase.exe -s $sourceIP -o $($prefix)_two -d $destinationIP -n $($prefix)_two -c
Start-Sleep -s 2
Write-Host "Copying Three"
.\CopyDatabase.exe -s $sourceIP -o $($prefix)_three -d $destinationIP -n $($prefix)_three -c
Start-Sleep -s 2
Write-Host "Copying Four"
.\CopyDatabase.exe -s $sourceIP -o $($prefix)_four -d $destinationIP -n $($prefix)_four -c
Write-Host "Finished Backup"
}
catch
{
write-host "EXCEPTION:"
write-host "Exception Type: $($_.Exception.GetType().FullName)"
write-host "Exception Message: $($_.Exception.Message)"
exit -1
}
It's working as I expect, except that $($prefix)_keyspace gives me prefix _keyspace where I want prefix_keyspace. I'm sure I can write a function or make a new variable for each concatenation, but I'm wondering if there's a command I can use for this that'll save me from having to do that. Thanks!
Replace the try block with this:
try
{
Write-Host "Starting Copy of Keyspaces to Dev"
Write-Host "Copying One"
.\CopyDatabase.exe -s $sourceIP -o ${prefix}_one -d $destinationIP -n ${prefix}_one -c
Start-Sleep -s 2
Write-Host "Copying Two"
.\CopyDatabase.exe -s $sourceIP -o ${prefix}_two -d $destinationIP -n ${prefix}_two -c
Start-Sleep -s 2
Write-Host "Copying Three"
.\CopyDatabase.exe -s $sourceIP -o ${prefix}_three -d $destinationIP -n ${prefix}_three -c
Start-Sleep -s 2
Write-Host "Copying Four"
.\CopyDatabase.exe -s $sourceIP -o ${prefix}_four -d $destinationIP -n ${prefix}_four -c
Write-Host "Finished Backup"
}
This should do your work. Not tested.
Related
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
I am trying to execute a PowerShell to execute a reg file remotly
This is what I have at the moment:
$computer = 'IP';
$username = 'user';
$password = 'password';
$reg = 'regedit /s //ip/teste.reg';
$reg_command = "psExec -i -d -c -f -s \\$computer -u $computer\$username -p $password `"$reg`"";
Write-Output "Inserting regestry file...";
Invoke-Expression $reg_command;
I have psExec in my computer, but I don't know how I would add the path executable for PSExec in the code.
I'm trying to pass username, db and pwd as variable to sqlcmd - but it does not seem to like it.
This works
#Run SQLCMD for each file
ForEach ($FileName in $FileNames)
{
Write-Host $FileName.BaseName
sqlcmd -S 123.database.net -d EMR -U user1-P mypassword -i $FileName.FullName
}
This does not work
#Run SQLCMD for each file
$db = "123.database.net"
$dbId = "user1"
$pwd = "mypassword"
ForEach ($FileName in $FileNames)
{
Write-Host $FileName.BaseName
sqlcmd -S $db -d EMR -U $dbId -P $pwd -i $FileName.FullName
}
Error message
sqlcmd : Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Login failed for user 'user1'..
sqlcmd has its scope .Make the variables as Global. Then it should pick it.
DO this:
#Run SQLCMD for each file
$global:db = "123.database.net"
$global:dbId = "user1"
$global:pwd = "mypassword"
ForEach ($FileName in $FileNames)
{
Write-Host $FileName.BaseName
sqlcmd -S $db -d EMR -U $dbId -P $pwd -i $FileName.FullName
}
Note: I have not taken into consideration that your second scriptlet is throwing any error in particular or not.
I have been trying both standard PS1 using what I read about using:
ECHO y | plink .....
But the issue I have is that plink is being saved on a network drive. I can call it using:
$plink = "P:\path\plink.exe"
echo y | &$plink -ssh -l user-pw password $addrss exit
&$plink -ssh -l user -pw password -m "P:\path\SCOTDiagScript.txt" $addrss
The issue I have is that if I run plink manually via cmd, I get output, that I need to read and possibly display to the user. Piping the last line to Out-File gives me nothing and if I try to call cmd to then redirect to a txt file, I get an error because the path for plink has a space in it; and I am using quotes.
I have also given using .NET a try, but doing a .StandardOutput.ReadToEnd() causes it to hang; deadlock maybe? Even though I am placing it well before the exit and I have it sleep a bit before any type of exit takes place:
$ps = New-Object -TypeName System.Diagnostics.Process
$ps.StartInfo.UseShellExecute = $false
$ps.StartInfo.RedirectStandardInput = $true
$ps.StartInfo.RedirectStandardOutput = $true;
$ps.StartInfo.FileName = "P:\path\plink.exe"
$ps.StartInfo.Arguments = "-ssh -l user -pw password $addrss"
[void]$ps.Start()
Start-Sleep -m 500
$ps.StandardInput.Write("cd c:/scot/bin`r")
Start-Sleep -m 500
$ps.StandardInput.Write("GetDiagFiles.exe`r")
Start-Sleep -m 500
$ps.StandardInput.Write("cd c:/temp`r")
Start-Sleep -m 500
$ps.StandardInput.Write("ls *.zip`r")
Start-Sleep -m 500
$ps.StandardInput.Write("cd c:/scot/monitor`r")
$Out = $ps.StandardOutput.ReadToEnd();
Start-Sleep -s 10
$ps.StandardInput.Write("exit`r")
$PlinkStreamWriter.Close();
if (!$ps.HasExited) { $ps.Kill() }
$Out
I'm sure I'm doing something wrong, but I have scoured over everything at MSDN and nothing.
Doing what you ask should be as easy as:
plink -ssh -l user -pw password -m script.txt > output.log
Where the script.txt contains your commands:
cd c:/scot/bin
GetDiagFiles.exe
cd c:/temp
ls *.zip
cd c:/scot/monitor
exit
If this does not work (as you claim you have tried something similar), give us more details about the problem.
You have not created a System.Diagnostics.ProcessStartInfo object to feed into the System.Diagnostics.Process object.
You needed to put `n at the end of the commands not `r, or you can remove them altogether when using the .WriteLine method
I tested the code below using some cmd.exe and made the alterations you need, it should work with plink.exe
$ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessStartInfo.UseShellExecute = $false
$ProcessStartInfo.RedirectStandardError = $true
$ProcessStartInfo.RedirectStandardInput = $true
$ProcessStartInfo.RedirectStandardOutput = $true
$ProcessStartInfo.FileName = "P:\path\plink.exe"
$ProcessStartInfo.Arguments = "-ssh -l user -pw password $addrss"
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo = $ProcessStartInfo
$Process.Start() | Out-Null
$Process.StandardInput.WriteLine("cd c:/scot/bin")
$Process.StandardInput.WriteLine("GetDiagFiles.exe")
$Process.StandardInput.WriteLine("cd c:/temp")
$Process.StandardInput.WriteLine("ls *.zip")
$Process.StandardInput.WriteLine("cd c:/scot/monitor")
$Process.StandardInput.WriteLine("exit")
$Process.WaitForExit()
$stdoutput = $Process.StandardOutput.ReadToEnd()
$erroutput = $Process.StandardError.ReadToEnd()
Write-Host "Standard Output: $stdoutput"
Write-Host "Error Output : $erroutput"
Write-Host "exit code: " + $Process.ExitCode
The following code, setting the -v parameter directly is working
$sqlcmd = #(Resolve-Path "$env:ProgramFiles\Microsoft SQL Server\*\Tools\binn\SQLCMD.EXE")[0]
$path1 = 'D:\somescript.sql'
& $sqlcmd -b -S NB-BK\SQLEXPRESS -d BK_Prod -U sa -P mypassword -l 180 -i $path1 -v Mandant=1 SAPMandant="009" SAPEinrichtung="0001"
But I need a way to set these values from a PowerShell variable.
I tried:
$sqlcmd = #(Resolve-Path "$env:ProgramFiles\Microsoft SQL Server\*\Tools\binn\SQLCMD.EXE")[0]
$path1 = 'D:\somescript.sql'
$sqlcmdparameters = 'Mandant=1 SAPMandant="009" SAPEinrichtung="0001" '
& $sqlcmd -b -S NB-BK\SQLEXPRESS -d BK_Prod -U sa -P mypassword -l 180 -i $path1 -v $sqlcmdparameters
I found this on SO, but it didn't help me.
I found the following solution for PowerShell V2
$sqlcmd = #(Resolve-Path "$env:ProgramFiles\Microsoft SQL Server\*\Tools\binn\SQLCMD.EXE")[0]
$path1 = 'D:\somescript.sql'
$cmdparameters = #(
'Mandant=1',
'SAPMandant="009"'
)
& $sqlcmd -b -S NB-BK\SQLEXPRESS -d BK_Prod -U sa -P mypassword -l 180 -i $path1 -v $cmdparameters
Try using start-process. That's what I do for Powershell command-line parsing issues. First try invoke operator (&) and if that doesn't work wrap it in a start-process call.
$tempFile = [io.path]::GetTempFileName()
$exitCode = (start-process -FilePath $sqlcmd -ArgumentList #"
-b -S NB-BK\SQLEXPRESS -d BK_Prod -U sa -P mypassword -l 180 -i $path1 -v $sqlcmdparameters
"# -Wait -RedirectStandardOutput $tempFile -NoNewWindow -Passthru).ExitCode
When using start-process typically you'll need to capture exitcode and also redirect output to temp file in get back the results. I'll then have some code to check $exitcode and cleanup temp file in try/catch/finally block