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.
Related
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.
Here is my PowerShell script that takes back up of Postgresql server in remote location.
Also postgres is installed in my local PC.
Set-Location 'C:\Program Files\PostgreSQL\12\bin\';
$env:PGPASSWORD = 'MyPassword';
$bkpBaseFolder = 'D:\dbBackup\';
$PGPATH="C:\Program Files\PostgreSQL\12\bin\pg_dump.exe";
$cdate = (Get-Date).ToString('dd-MMM-yy_HH-mm');
$NewFolder = $bkpBaseFolder + $cdate + '\';
New-Item -ItemType Directory -Force -Path $NewFolder;
$dbs = .\psql -h mysite.com -U postgres -c 'SELECT datname FROM pg_database WHERE datistemplate = false;'
foreach($db in $DBs) {
$fileName = $NewFolder + $db + '.bkp';
& $PGPATH -h mysite.com -U postgres -f $fileName -d $db
}
I want to move this script to Azure Functions with Powershell to run on specified time everyday.
How do I set Path variables of pg_dump or other local paths without installing it?
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
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