Running Powershell via SQL Server Job - sql

I have a very basic script which runs fine on my local PC. It simply backs up some folders and their contents then adds a date stamp on the folder name.
The script backs up folders on two different servers (Server2 & Server3).
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
#Part 1
Copy-Item -Path "\\Server3\Example Location" -Destination "\\Server3\Example Location_$(get-date -f yyyyMMdd)" -Recurse
#Part 2
Copy-Item -Path "\\Server2\Example Location" -Destination "\\Server2\Example Location_$(get-date -f yyyyMMdd)" -Recurse
It runs both parts perfectly in the below environments:
On my local PC
When I remotely connect to Server 2 and right click > Run with PowerShell
When I remotely connect to Server 2 and edit > Run script
However, when I try to automate this and create a SQL Server Agent Job (again, on Server 2) only Part 2 actually backs up. The job successfully completes, but Part 1 appears to get ignored (i.e. running on Server 2, backing up on Server 3).
Any ideas why running as a SQL job would cause this?
n.b. The job is set to run as 'SQL Server Agent Service Account'.

Couple things...
If you run your PS script as a step type Operating system (CmdExec) then there will never be an error message returned to the SQL-Server Job.
With that being said, if your SQL-Server Agent Service account does not have access to the \Server3... folders, the copy will fail and as above said, no error message will be transferred to the calling SQL-Agent Job.

Related

bcp not running from task scheduler

I am trying to schedule a bcp job in server 2012 task scheduler. My batch file works fine when I double-click on it. It includes this line:
bcp "SELECT * FROM [TIME_KEEPER]" queryout D:\DATA\TIMESHEET_DBASE.csv -S 10.0.0.54 /c /t, -T
The file is created from the command line. Scheduler has:
Action: start a program
Script: D:\DATA\myBatch.bat
Start in: D:\Data
I am using the same account for other scheduled tasks and they are running fine.
Sounds like a security issue.
Do any of the other scheduled tasks use the bcp executable and connect to the same server pulling data from teh same table? If not then you have to track down the security being used.
When you double click your batch, it is run as the account you are logged in as. Is it possible that your scheduled tasks are running as a different account than what you are logged in as?
As a test, are you able to log in to the windows server using the same account the task scheduler is executing the tasks (assuming they are different)?
Should get similar error at that point.
Just a start.

Running SQL against multiple DB in azure pipeline

I want to set up the step in release process for azure pipeline where I can run the SQL from the file checked into the repo against multiple databases.
In my environment, I have one central db, one of the table for e.g "Control" table, keeps the connection to all the databases against which I need to run the sql during the deployment.
What I dont want to do is to setup the deployment step for each database. Is Powershell my only friend?
If so, how can I let powershell know what is the SQL in the file checked in during the deployment?
What I dont want to do is to setup the deployment step for each database. Is Powershell my only friend? If so, how can I let powershell know what is the SQL in the file checked in during the deployment?
In your case, Powershell seems to be the most appropriate.
In order to get the SQL in the file checked in during the deployment, we could use the powershell scripts to get the file names and paths, like:
$files=$(git diff HEAD HEAD~ --name-only)
$temp=$files -split ' '
$count=$temp.Length
echo "Total changed $count files"
For ($i=0; $i -lt $temp.Length; $i++)
{
$name=$temp[$i]
echo "this is $name file"
Copy-Item "$name" -Destination "$(System.DefaultWorkingDirectory)\SQLDeploymentFolder"
}
Check the ticket for some more details.
Then, we could use the extension Run SQL Server Scripts or Run SQL / SQLCMD Scripts passing multiple SQLCMD variables to all SQL Scripts in a folder.
Hope this helps.

Trying to run batch file in powershell remotely is not working

I am currently administering a Selenium Grid with 20 remote PCs acting as nodes to a single Hub located on a server. At the moment I have to remote in to each machine when I want to restart the hub or nodes and clear up any stale chromedriver or chrome instances. I am trying to automate this process via Powershell.
So far I have manage to write the ps scripts to kill any instances of chrome, chromedriver and java on the PCs and then restart the hub or node. They work when started locally on each machine when but fail when I try and execute them via a PSSession.
I have enabled remote sessions on each machine successfully and I can Invoke-Commands that will kill the existing instances of java and chrome but I can't restart the hub or nodes.
Example of Hub powershell script:
#This script kills any existing java process and runs StartHub.bat
Set-Location C:\Selenium
kill -Name java -Force -PassThru -ErrorAction Continue
Start-Process -FilePath "C:\Selenium\StartHub.bat" -PassThru -Verbose
The bat file is as follows:
java -jar C:\Selenium\selenium-server-standalone-3.4.0.jar -role hub -hubConfig "V:\ServerFiles\hubconfig.json"
I have been testing with the execution policy unrestricted and my network administrator has changed GPO's to allow my to start java processes remotely but it's just not working. I've tried several approaches which I have listed below:
1: Entering a PSSession on remote server and calling the ps1 file:
C:\RestartHub.ps1
The result being that the existing hub instance is killed but a new one does not open.
2: I have then tried to Start a job with a ScriptBlock calling the cmd script to start the batch file:
Set-Location C:\Selenium
kill -Name java -Force -PassThru -ErrorAction Continue
Start-Job -ScriptBlock{cmd /c start "C:\Selenium\StartHub.bat"} -Name Hub -Verbose
This again kills the existing hub instance but the start script does not run or fails silently.
I have looked through the security logs on the remote machine to see if there are any issues there but the PSSession seems to be correct using the right user with full admin rights.
I have also changed the ExecutionPolicy on the remote machine to restricted to see if an access denied error is display, which it was. I changed back to unrestricted and error went away.
I'd be grateful for any ideas.
Start-Process will start a process from an executable, you cannot use a bat file as an executable, -FilePath expects an executable's path
See below,
Start-Process cmd -Argumentlist "C:\Selenium\StartHub.bat" -PassThru -Verbose

Executing commands on command prompt of a remote computer

I need to execute the command :- Powermt display dev = all in the command prompt of a remote computer. How do I do that ?
If you have PowerShell 2.0 or higher on both computers and can enable remoting on the remote computer by execute Enable-PSRemoting -Force, then from an elevated/admin PowerShell prompt you can run:
Invoke-Command -ComputerName remotepcname -ScriptBlock { <commands to execute remotely> }
This will execute the commands remotely and return the results to the local computer.
Here's another alternative to try where psexec and powershell fail. It's convoluted and hackish, but at least it's something else to try. :)
Firstly, share a folder on your own machine. Make sure an account with admin rights on the remote machine has write access to this share you create. Then execute the following:
wmic /node:remoteComputerAddr /user:adminOnRemoteComputer /password:adminPassword process call create "cmd.exe /c powermt display dev=all >>\\localComputerAddr\shareName\results.txt"
#type "c:\local\path\to\share\results.txt"
Unfortunately, wmic doesn't show you the output of the process it creates. That's why you enable a share on your local workstation, then redirect the output from the remote command to your share.
More info.

Powershell Transcript is empty when running script from SQL Agent Job in 2005 SQL Server

I have a complex Powershell script that gets run as part of a SQL 2005 Server Agent Job. The script works fine, but it uses the "Start-Transcript $strLogfile -Append" command to log all of it's actions to a transcript file. The problem is that the transcript is always empty. It adds the header and footer to indicate that the transcript is starting and stopping, but it doesn't actually log anything. Example:
**********************
Windows PowerShell Transcript Start
Start time: 20100304173001
Username : xxxxxxxxxxxx\SYSTEM
Machine : xxxxx-xxx (Microsoft Windows NT 5.2.3790 Service Pack 2)
**********************
**********************
Windows PowerShell Transcript End
End time: 20100304173118
**********************
When I execute the script from a command prompt or start -> run everything works just fine. Here is the command used to run the script (same command used in the Operating system CmdExec step of the SQL Agent Job)
powershell.exe -File "c:\temp\Backup\backup script.ps1"
I first thought it must have something to do with the script running under the System account (default SQL Agent account), but even when I tried changing the SQL Agent to run under my own personal account it still created a blank transcript.
Is there any way to get PowerShell Transcripts to work when executing them as part of a 2005 SQL Server Agent Job?
If your script uses native commands (console exes), Start-Transript does not log any of that output. This issue has been logged on Connect, you can vote on it. One way to capture all input is to use cmd.exe:
cmd /c powershell.exe -file "C:\temp\backup script.ps1" > backup.log
sqlps.exe does not implement certain methods including the method that supports write-host. This may explain why you are not seeing output using Start-Transcript when running sqlps.exe from a SQL Agent Powershell jobstep. See http://blogs.msdn.com/mwories/archive/2009/09/30/the-use-of-write-host-and-sql-server-agent-powershell-job-steps.aspx for more information.
I am still not sure why the Powershell Transcript is empty, but we found a workaround. Under the CmdExec step of the SQL Job there is an advance option to capture the output to a file, which combined with the "Append output to existing file" option and using a Logfile.rtf extension is about the same as the Powershell transcript. This way anything that gets printed to the host from the Powershell script (including native console executables piped to "| out-host") will be captured in the log file.