Cannot execute powershell file with function call in Transact SQL script - tsql

I have a problem with my Transact SQL script, I made a procedure in Transact SQL which has to execute a powershell script with a function. When I execute the file and method in the Command Prompt it works but if I put the command in Transact SQL it gives me an error saying that it doesn't recognize the command. I hope someone could help me.
Command Prompt command
powershell -command "& { . C:\Users\mslaats\Desktop\Databasescripts\Powershell\GmailLibrary.ps1; SendGmail "<email address>" "subject" "body" }"
Transact SQL script
PRINT 'Use the Divestar database'
USE [Divestar]
GO
PRINT 'Grant access to execute through a kind of cmd'
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
-- Delete the old procedure
PRINT 'Drop procedure'
DROP PROCEDURE IF EXISTS [dbo].[SendEmail]
GO
-- Procedure --
PRINT 'Create procedure to send an email'
GO
CREATE PROCEDURE [dbo].[SendEmail]
#To VARCHAR(1024),
#Subject VARCHAR(1024),
#Content VARCHAR(1024)
AS
BEGIN
DECLARE #CMD VARCHAR(1024)
SET #CMD = 'powershell -command "& { . "C:\Users\mslaats\Desktop\Databasescripts\Powershell\GmailLibrary.ps1"; SendGmail "<email address>" "onderwerp" "bodytje" }"'
PRINT #CMD
EXEC xp_cmdshell #CMD
END
GO
Transact SQL script error
. : The term
'C:\Users\mslaats\Desktop\Databasescripts\Powershell\GmailLibrary.ps1' is not
recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify
that the path is correct and try again.
At line:1 char:7
+ & { . C:\Users\mslaats\Desktop\Databasescripts\Powershell\GmailLibrary.ps1;
Send ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\mslaat...mailLibrary.p
s1:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
SendGmail : The term 'SendGmail' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At line:1 char:77
+ & { . C:\Users\mslaats\Desktop\Databasescripts\Powershell\GmailLibrary.ps1;
Send ...
+
~~~~
+ CategoryInfo : ObjectNotFound: (SendGmail:String) [], CommandNo
tFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
NULL

After encountering this same problem, I've found out that I needed to check the ExecutionPolicy on both machines. I knew my ExecutionPolicy was fine on my machine, but I checked the SQL server machine via:
EXEC master..xp_cmdshell 'powershell -command "& { Get-ExecutionPolicy }" '
which returned Restricted (which means that no Powershell script can run, and hence I ran into the same error message that you did).
Additionally, I also made sure my script was stored in a location that SQL Server had permission to access. You could check this in your case with a command like:
EXEC master..xp_cmdshell 'powershell -command "& { dir C:\Users\mslaats\Desktop\Databasescripts\Powershell }" '
And that command will let you know if SQL can see your script or not. In my case, I put my script in a shared network location I knew SQL could already access.

Related

The term 'EXEC' is not recognized as the name of a cmdlet Powershell

I have an SSIS dtsx package that I want to run using PowerShell. Below is what I am running in powershell.
EXEC xp_cmdshell '"C:\Program Files\Microsoft SQL Server\130\DTS\Binn\DTExec.exe" /f "F:\SqlExport\New package.dtsx"'
Unfortunately I get the below error, and I dont know why
EXEC : The term 'EXEC' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At line:1 char:1
+ EXEC xp_cmdshell '"C:\Program Files\Microsoft SQL Server\130\DTS\Binn ...
+ ~~~~
+ CategoryInfo : ObjectNotFound: (EXEC:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I have enabled the xp_cmdshell in SQL Server using below command as well
EXEC xp_cmdshell is a T-SQL statement for launching shell commands via cmd.exe.
I presume the intent is to have PowerShell execute the command that starts with executable path "C:\Program Files\Microsoft SQL Server\130\DTS\Binn\DTExec.exe", launched from your T-SQL script via EXEC xp_cmdshell[1].
Instead, your error message implies that PowerShell executed the entire line, which predictably failed: PowerShell has no EXEC command (and there is no external program by that name on your system).
That said, PowerShell is neither needed here, nor would it enter the picture, if your EXEC xp_cmdshell line had been executed by SQL Server (via a T-SQL script).
In fact, your T-SQL command should work as-is (invocation of an external program with arguments, via cmd.exe), if properly executed by SQL Server.
[1] Update: If the intent is simply to launch the command from PowerShell
& "C:\Program Files\Microsoft SQL Server\130\DTS\Binn\DTExec.exe" /f "F:\SqlExport\New package.dtsx"`
Note the need for &, the call operator, to tell PowerShell that the double-quoted string that follows is the name of an executable to invoke.

Running a PowerShell Script .PS1

I am trying to generate a MachineKey for my application using the PowerShell script found in kb2915218.
I have copied the function into notepad and saved as a .PS1 file. Now if I look at this file through explorer it is being recognised as a PowerShell file.
I then have run PowerShell and CD to the directory of my .PS1 file.
I then ran the following command:
Set-ExecutionPolicy Unrestricted
followed by:
.\Powershell-Generate-MachineKey.ps1
(the name of my script). And finally I then tried running the command
Generate-MachineKey
However I get the message:
Generate-MachineKey : The term 'Generate-MachineKey' is not recognized as the
name of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:1
+ Generate-MachineKey
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Generate-MachineKey:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Can someone please tell me where I am going wrong here?
The script just defines a function, so if you execute it like this:
.\Powershell-Generate-MachineKey.ps1
it won't do anything, because the function isn't invoked anywhere and also isn't made available in the current context. For the latter you need to dot-source the script
. .\Powershell-Generate-MachineKey.ps1
The dot-operator basically executes the script in the current context instead of a child context. That way the definitions from the script become available in the current context, and you can invoke the function like this:
Generate-MachineKey

Not able to execute AWS Powershell tool cmdlet in TFS Post build script

I am trying to execute the few aws cmdlet command in post build script with TFS build. I have a AWS SDK tool is installed in build controller. I am able to run the same commands manually in Build controller. But when i invoke those commands in TFS post build script. It's giving me error that its not able to find the cmdlet installed on the build controller. I tried to change the execution policy but didn't help. I have an execution policy - bypass right now. script is executing but only the commands is not able to execute. I am thinking that it's issue because of something like Execution policy. Do we need to check anything else same like execution policy while we invoke any third party cmdlet from power shell.
Commands:
Set-AWSCredentials -AccessKey -SecretKey
Set-DefaultAWSRegion -Region us-east-1
Write-S3Object -BucketName agero-source-package -File "\\b tfadfa\adfa\adf\asdf\adsf\asdf\asd\xyz.zip"
Error:
Set-DefaultAWSRegion : The term 'Set-DefaultAWSRegion' is not recognized as the name of a cmdlet, function, script
file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct
and try again.
At \\b-tfsbc001wv\c$\MV\BuildETA-API.ps1:41 char:26
+ cd "\\b-tfsbc001wv\C$" | Set-DefaultAWSRegion -Region us-east-1
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Set-DefaultAWSRegion:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Write-S3Object : The term 'Write-S3Object' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
At \\b-tfsbc001wv\c$\MV\BuildETA-API.ps1:43 char:26
+ cd "\\b-tfsbc001wv\c$" | Write-S3Object -BucketName agero-source-package -File " ...
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Write-S3Object:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
From the error messages, it would appear that the AWSPowerShell module cannot be found/automatically loaded by whatever account the TFS build process is running as.
Check that the module is installed to a globally available location under which the version of PowerShell you have searches for modules or, that the path to the module folder is present in the $PSModulePath environment variable for the TFS build account.
I got the same error on my TFS Build Agent:
Set-DefaultAWSRegion : The term 'Set-DefaultAWSRegion' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
After I installed AWS Command Line Interface x64 bit (AWSCLI64) I was able to set the Set-DefaultAWSRegion by stepping over the line of code.
I was getting this error until I ran Powershell using "Run as Administrator." So the problem might be with permissions.

Colon as string in parameters

Is there a way to exclude the colon (:), so you can print it via parameters as String?
Little example:
PowerShellTest.ps1:
param (
[string]$message="Error: No message defined!"
);
"Info: Test-Information"
$message;
if you now starts this script via powershell:
powershell.exe D:\PowerShellTest.ps1 -message "Error: Test-Error"
Now you get only the output string Error: the rest will be cut off
What do I have to do to get the whole string Error: Test-Error?
The problem is not the colon, but the space. You need to escape it using the backtick:
powershell.exe D:\PowerShellTest.ps1 -message 'Error:` Test-Error'
Use single quotes ' instead of double quotes " like so,
C:\temp>powershell c:\temp\test.ps1 -message 'Error: Test-Error'
Info: Test-Information
Error: Test-Error
Why are you running it that way? When you run powershell.exe from inside Powershell you are forcing the arguments to go through the old Windows cmd.exe style command line processing.
Instead you should just invoke your script directly:
PS C:\scripts> .\PowershellTest.ps1 -message "Error: Test-Error"
Info: Test-Information
Error: Test-Error
This way all of the arguments will pass right through without being converted to strings, having double quotes stripped and then being re-parsed.
If you get an error because running scripts is not permitted then the answer is to change your execution policy, not to start another copy of powershell.exe:
PS C:\scripts> .\PowershellTest.ps1 -message "Error: Test-Error"
.\PowershellTest.ps1 : File C:\scripts\PowershellTest.ps1 cannot be loaded because running scripts is disabled on this
system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ .\PowershellTest.ps1 -message "Error: Test-Error"
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
If you see this error then start a Powershell window using the 'run as administrator' option and enter the command:
Set-ExecutionPolicy RemoteSigned
Close the administrator powershell and restart any other powershell windows you have running and now you should be able to run locally created scripts without any problems.

Appfabric Powershell error "The term 'Get-CacheStatistics' is not recognized as the name of a cmdlet.."

I'm calling the simple following Powershell AppFabric command:
powershell -noexit c:\scripts\ApplyClusterConfig.ps1
and the script just contains:
Get-CacheStatistics
and I'm getting the following error:
The term 'Get-CacheStatistics' is not recognized as the name of a cmdlet, funct
ion, script file, or operable program. Check the spelling of the name, or if a
path was included, verify that the path is correct and try again.
At C:\scripts\ApplyClusterConfig.ps1:1 char:20
+ Get-CacheStatistics <<<<
+ CategoryInfo : ObjectNotFound: (Get-CacheStatistics:String) [],
CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I've done everyting that I can find on the web including
Set-ExecutionPolicy Unrestricted
and using the .\ to refer to the file:
powershell -noexit .\ApplyClusterConfig.ps1
and setting the environment path to include c:\Scripts
But the error keeps persisting. Can anyone help please because I've run out of all google options. Thanks.
As the errors says, it is not able to find Get-CacheStatistics as a cmdlet, function, script file, or operable program. You need to laod the necessary modules.
Look here for guidance on how to load the necessary modules to run AppFabric cmdlets: http://msdn.microsoft.com/en-us/library/ee677295.aspx
You will probably have to add one or more of the following imports ( maybe in your script):
Import-Module ApplicationServer
Import-Module distributedcacheconfiguration
Import-Module distributedcacheadministration
Execution policy has nothing to do with this error and you are running the script fine.