I am currently trying to run a Powershell script through SQL Server Agent, which completes its task without error if I run it through Powershell ISE on the desktop. The simple script is below (it's only being used for testing):
$test = "G:\test.txt"
if (Test-Path $testFile)
{
Remove-Item $test
}
When I run this through SQL Server Agent, it produces a successful output - no errors whatsoever, but does show that it's being run as a different user in the job history log, for instance domain\localmachine, whereas when I run the script through Powershell ISE, it shows domain\you.
As a note, I can't confirm this manually because what I tried to do was run the below script both locally and through SQL Server Agent in a job to see the output, but the job failed (and thus why I suspect it's a user issue). Therefore, I'm trusting SQL Server Agent as to the domain\locallmachine is running the job (the reason it won't delete the file).
([Environment]::UserDomainName + "\" + [Environment]::UserName) | out-file pssaved.txt
"$env:userdomain\$env:username" | out-file -append pssaved.txt
[Security.Principal.WindowsIdentity]::GetCurrent().Name | out-file -append pssaved.txt
## Locally this produces domain\you
## On SQL Server Agent, I receive the error: The error information returned by PowerShell is: 'SQL Server PowerShell provider error: Path SQLSERVER:\pssaved.txt does not exist. Please specify a valid path.'
Is there a way, through SQL Server Agent to run a job as my domain user, for instance domain\you instead of the domain\localmachine (at least, this would eliminate this possibility of an error)?
You can use a proxy for this. Check it out.
Related
I upgraded a Windows Server 2012 to 2019, but kept the SQL Server (110)
My sql agent jobs stopped working, the ones using PowerShell commands.
I get the error message
A job step received an error at line 1 in a PowerShell script.
The corresponding line is 'import-module SQLPS -DisableNameChecking'.
Correct the script and reschedule the job.
The error information returned by PowerShell is:
'File C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\SQLPS\Sqlps.ps1
cannot be loaded because the execution of scripts is disabled on this system.
Please see "get-help about_signing" for more details.
The Sqlps.ps1 IS signed with a valid signature, and I even temporarily tried to Set-ExecutionPolicy Unrestricted , but that didn't help either. (All suggested by chatgpt ;-) )
My script should download a file from an url and place it in c:\tmp
EDIT:
Solved, I set the script execution policy to "Allow local scripts and remote signed scripts" in group policy for computer; it was pereviously "Not Configured"
If the effective execution policy is Restricted, even signed scripts won't help you.
What matters is what the effective execution policy is for the user identity that your services / scheduled tasks run as, which you can control as follows:
Ad hoc, in a given PowerShell CLI call (powershell.exe [-Command] ... / powershell.exe -File ...), precede the (possibly implied) -Command / -File parameter with an -ExecutionPolicy argument, e.g. - if you fully trust the script (eventually) getting invoked - -ExecutionPolicy Bypass
Persistently, via a machine-wide execution policy (requires elevation (administrative privileges)):
Via Set-ExecutionPolicy -Scope AllUsers
Via GPO policies (which override persistent Set-ExecutionPolicy configurations).
See this answer for additional information.
I have a fairly straightforward Powershell script that is ran as part of a Bamboo deployment which includes a call to Invoke-DbaQuery to run sql scripts against a database.
After an incident with a bad script left our deployment hanging for hours, I am attempting to implement a timeout which I would expect to cause the Invoke-DbaQuery to fail, and thus the script to fail, and likewise the Bamboo deployment after a set amount of time.
However, Powershell seems to be ignoring the -queryTimeout parameter of Invoke-DbaQuery. Running the following commands calling an intentionally long running script and an arbitrarily short timeout, the query continues to execute hours after the timeout.
To eliminate variables I am testing this directly on Powershell on the server with the sql instance.
$path = "c:\somescript.sql"
$server = "localhost"
Invoke-DbaQuery -file $path -SqlInstance $server -Database MyDatabase -QueryTimeout 30
I have a PowerShell script:
Invoke-Sqlcmd -ServerInstance "PRODUCTION" -Database "DATABASE" -InputFile "E:\DW_Exports\cdd.sql" | Export-Csv "E:\DW_Exports\Pearsonvue\CDD.csv" -NoTypeInformation
When I run this manually in ISE, works fine, no problems.
However, when I set it up as a SQL Agent job it just returns a blank file. No errors reported, it says it was successful, but all I end up with is a blank file.
I've tried the process with very simple queries (just changing the input file the PowerShell points to), and it works fine. So we can rule out SQL Server Agent access issues to the file location or running PowerShell. It just doesn't work for this specific query.
Whats also odd is that sometimes after I run the job, if I try to run the PowerShell script manually it says I don't have access to the file location unless I delete the blank file, then it works fine again.
Any ideas?
I am trying to run a PowerShell script from a windows batch file. This is a SharePoint related script that uses Import-SPData.
This works without any issue when using USERA's login. However, if I try to run the same batch file from USERB's login, I get the error below:
c:\PS>ExecMyPowershellScript.bat
c:\PS>C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -psconsolefile "
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG\P
OWERSHELL\Registration\psconsole.psc1" -command "c:\ps\MyPSScript.ps1"
The local farm is not accessible. Cmdlets with FeatureDependencyId are
not registered.
Import-SPData : Cannot access the local farm. Verify that the local
farm is properly configured, currently available, and that you have
the appropriate permissions to access the database before trying
again.
At C:\ps\Run_MyPSScript.ps1:5 char:18
USERB has permissions to run the bat and the ps1 files.
You are assuming, the error is related to permission to either the bat or the powershell file.
The error you get comes from a SP cmdlet, so you have successfully opened the bat file and successfully run the powershell script.
Which then throws an error. UserB has not the apropriate rights to the farm. Hence the error:
...and that you have the appropriate permissions to access the
database before trying again.
Compare the permissions from UserA and UserB on the farm and the database.
Or you could use a sledgehammer and log into UserA to run the following powershell script:
$db = Get-SPDatabase | Where {$_.Name -eq "SharePoint_ConfigDB"}
Add-SPShellAdmin "domain\UserB" -database $db
I am writing a powershell script that will automate a dev environment deployment and I've hit a problem with attaching the db's. I am adding the 2 snap ins SqlServerCmdletSnapin100 and SqlServerProviderSnapin100 and using SQLSERVER:\SQL\localhost\SQLEXPRESS and the AttachDatabase method. This is working well and if I use DetachDatabase method in the same way I can re-run the script continually. My problem arises when I detach from the management studio and try to run the script again. No matter what I do here (permissions etc.) the script will continually fail from this point on with error:
Exception calling "AttachDatabase" with "2" argument(s):
"Attach database failed for Server 'localhost\SQLEXPRESS'. "
If I change the name of the database I am attaching as the script will work again. Is there something in a system db that would be hanging onto the Database or database files that I need to remove as well?
SMO uses nested error objects, so I'm wondering what the base error message states. If you run this statement:
$error[0] | fl -force
What error message do you get
Update
Ran a quick test:
Detach database "hsg" from my local instance using SSMS and successfully attached with this script:
PS SQLSERVER:\SQL\WIN7BOOT\SQL1> $s = get-item .
PS SQLSERVER:\SQL\WIN7BOOT\SQL1> $s.AttachDatabase("hsg",$sc)
PS SQLSERVER:\SQL\WIN7BOOT\SQL1> $sc = new-object System.Collections.Specialized.StringCollection
PS SQLSERVER:\SQL\WIN7BOOT\SQL1> $sc.Add("C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL1\MSSQL\DATA\hsg.mdf")
PS SQLSERVER:\SQL\WIN7BOOT\SQL1> $sc.Add("C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL1\MSSQL\DATA\hsg_log.ldf)
I detached a database using SQL Server Management Studio and used the following code to attach the database back to the same instance. It worked Ok except that the attached database did not get the original name although files were the same.
PS SQLSERVER:\sql\Hodentek8\RegencyPark\databases>
$files = new-object system.collections.specialized.stringcollection
$files.add("C:\Program Files\Microsoft SQLServer\MSSQL11.REGENCYPARK\MSSQL\DATA\Feb6.mdf")
$files.add("C:\Program Files\Microsoft SQL Server\MSSQL11.REGENCYPARK\MSSQL\DATA\Feb6_log.ldf")
$server=new-object Microsoft.SqlServer.Management.Smo.Server('Hodentek8\RegencyPark')
$db=new-object Microsoft.SqlServer.Management.Smo.Server
$dbname="feb6"
$server.AttachDatabase($db,$files)
Some details are here:
http://hodentekmsss.blogspot.com/2015/04/attaching-detached-database-in-sql.html
perhaps instead of localhost\SQLExpress you should use:
I found this fix for some of my code which returned the same error:
$srv = new-object Microsoft.SqlServer.Management.Smo.Server 'Hodentek8\RegencyPark'
Replace 'Hodentek8\RegencyPark' by ("(local)") for the default instance
Example here:
http://hodentekmsss.blogspot.com/2015/04/counting-sql-server-configuration.html