{"id":105,"date":"2015-03-04T00:00:00","date_gmt":"2013-01-01T00:00:00","guid":{"rendered":"https:\/\/www.sqlhammer.com\/blog\/running-powershell-in-a-sql-agent-job"},"modified":"2026-03-18T21:51:38","modified_gmt":"2026-03-18T21:51:38","slug":"running-powershell-in-a-sql-agent-job","status":"publish","type":"post","link":"https:\/\/sqlhammer.com\/index.php\/2015\/03\/04\/running-powershell-in-a-sql-agent-job\/","title":{"rendered":"Demonstration"},"content":{"rendered":"<p>When creating a\u00a0SQL Agent Job to execute\u00a0a PowerShell script, you have to decide which way that you want the PowerShell to run. Depending upon which version of SQL Server that you are using and which job step type that you choose, you might be running in different versions of PowerShell with different execution policies. I will demonstrate the behaviors.<\/p>\n<h2>tl;dr<\/h2>\n<p>Executable<br \/>\nExecution Policy<br \/>\nPowerShell Version<\/p>\n<p>2008 R2 \u2013 PowerShell type<br \/>\nSQLPS.exe<br \/>\nRemoteSigned<br \/>\n2.0<\/p>\n<p>2008 R2 \u2013 CmdExec type<br \/>\npowershell.exe via cmd.exe<br \/>\nSystem Configured<br \/>\nLatest Installed<\/p>\n<p>2012 \u2013 PowerShell type<br \/>\nSQLPS.exe<br \/>\nRemoteSigned<br \/>\n2.0<\/p>\n<p>2012 \u2013 CmdExec type<br \/>\npowershell.exe via cmd.exe<br \/>\nSystem Configured<br \/>\nLatest Installed<\/p>\n<p>2014 \u2013 PowerShell type<br \/>\nSQLPS.exe<br \/>\nRemoteSigned<br \/>\n4.0<\/p>\n<p>2014 \u2013 CmdExec type<br \/>\npowershell.exe via cmd.exe<br \/>\nSystem Configured<br \/>\nLatest Installed<\/p>\n<h1>Demonstration<\/h1>\n<p>First we\u2019ll create a simple PowerShell script which will output the executable path and script path, PowerShell version and execution policy to a log file. We will then run this script through the SQL Agent on a SQL Server 2008 R2, 2012, and 2014 instance. We will also test different job step types.<\/p>\n<pre><code class=\"language-\">param([string]$filePath)\n[environment]::commandline | Out-File $filePath\n$version = $PSVersionTable.PSVersion\n\"Version: $version\" | Out-File $filePath -Append\n[string]$executionPolicy = Get-ExecutionPolicy\n\"Execution Policy: $executionPolicy\" | Out-File $filePath -Append<\/code><\/pre>\n<p>For setup purposes, this is what my PowerShell environment looks like outside of SQL Server. NOTE: The powershell.exe is being used, we are using PowerShell version 4.0, and the system execution policy is set to Unrestricted.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-Console.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-Console.jpg\" alt=\"\" \/><\/a><\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-Console-log.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-Console-log.jpg\" alt=\"\" \/><\/a><\/p>\n<h2>Test 1: SQL Server 2008 R2 using PowerShell job step<\/h2>\n<p>On a SQL Server 2008 R2 instance I have created a job with a single step which is configured as follows. Note the\u00a0<strong><em>Type<\/strong><\/em> selection.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-2008R2.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-2008R2.jpg\" alt=\"\" \/><\/a><\/p>\n<p>Here is the output. What you will notice is that SQL Server 2008 R2 has taken all of our system configurations out of our hands. Powershell.exe is no longer even being called, instead SQLPS.exe is being called. SQLPS.exe is a mini-shell which was made before the SQLPS module was created and is compiled with a limited sub-set of PowerShell version 2.0 cmdlets. See more details <a href=\"http:\/\/www.sqlhammer.com\/blog\/t-sql-command-line-options-part-5-sqlps\/\">here<\/a>. The mini-shell is also run in RemoteSigned mode, regardless of the system configured value.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-2008R2-log.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-2008R2-log.jpg\" alt=\"\" \/><\/a><\/p>\n<h2>Test 2: SQL Server 2008 R2 using Operating System\u00a0job step<\/h2>\n<p>In this test we will experiment with the Operating System (CmdExec) job step with no other changes except for modifying the script for cmd.exe syntax.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2008R2.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2008R2.jpg\" alt=\"\" \/><\/a><\/p>\n<p>As you can see below, by using the Operating System job step, we have taken back control over the system settings and ran the script in our currently install version of PowerShell. What is important to note with this configuration is that, in 2008 R2, this is the only way that you can use a version of PowerShell other than 2.0. Also, it is the only way for you to use the system defined setting for execution policy.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2008R2-log.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2008R2-log.jpg\" alt=\"\" \/><\/a><\/p>\n<h2>Test 3: SQL Server 2012 using PowerShell job step<\/h2>\n<p>Now we will redo test #1 but, this time, it will run on a SQL Server 2012 instance. We expect to see a behavior change because, with version 2012, the SQLPS module was created which removed the need of\u00a0the mini-shell for assembly packaging.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-2012.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-PoSh-2012.jpg\" alt=\"\" \/><\/a><\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/agent-2012.png\" alt=\"\" \/><\/p>\n<p>The results here were unexpected. I was having a discussion with Allen White (<a href=\"http:\/\/sqlblog.com\/blogs\/allen_white\/default.aspx\">b<\/a> | <a href=\"https:\/\/twitter.com\/sqlrunr\">t<\/a>) several months ago and our belief was that SQL Server 2012 would use the native PowerShell.exe rather than SQLPS.exe. This appears to not be true, I wonder if SQL Server 2014 implemented that feature or not.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/allen-white-posh-agent-tweets.png\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/allen-white-posh-agent-tweets.png\" alt=\"\" \/><\/a><\/p>\n<h2>Test 4: SQL Server 2012 using Operating System job step<\/h2>\n<p>In this test we will be using the Operating System (CmdExec) method again, just in SQL Server 2012. Here we expect no change from test #2 because both are essentially using cmd.exe\u00a0and SQL Server versions do not affect cmd.exe at all.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012.jpg\" alt=\"\" \/><\/a><\/p>\n<p>As expected, this method, in SQL Server 2012, grants you full control of the version and settings at the system level.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012-log.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012-log.jpg\" alt=\"\" \/><\/a><\/p>\n<h2>Test 5: SQL Server 2014 using\u00a0PowerShell job step<\/h2>\n<p>Once again we will redo test #1 but, this time, it will run on a SQL Server 2014 instance.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/agent-2014-step.png\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/agent-2014-step.png\" alt=\"\" \/><\/a><\/p>\n<p>What is interesting here is that SQLPS.exe is still used but the PowerShell Version is 4.0. It appears that the SQLPS.exe mini-shell was updated with SQL Server 2014 to use the newer PowerShell version rather than start using PowerShell.exe. It is my guess that this was the chosen method because SQLPS.exe guarantees that all of the appropriate assemblies are available for interaction with SQL Server. We wouldn\u2019t have to add initialization to our scripts such as\u00a0<em>Import-Module SQLPS -DisableNameChecking<\/em>.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/agent-2014.png\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/agent-2014.png\" alt=\"\" \/><\/a><\/p>\n<h2>Test 6: SQL Server 2014 using Operating System job step<\/h2>\n<p>In this test we will be using the Operating System (CmdExec) method once again, just in SQL Server 2014. Here we expect no change from test #2 &#038; #4 because both are essentially using cmd.exe\u00a0and SQL Server versions do not affect cmd.exe at all.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012.jpg\" alt=\"\" \/><\/a><\/p>\n<p>As expected, this method, in SQL Server 2014, grants you full control of the version and settings at the system level.<\/p>\n<p><a href=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012-log.jpg\"><img decoding=\"async\" src=\"http:\/\/www.sqlhammer.com\/blog\/wp-content\/uploads\/2014\/10\/Test-cmdln-2012-log.jpg\" alt=\"\" \/><\/a><\/p>\n<h2>Conclusions<\/h2>\n<p>Use the below table to identify how SQL Server Agent jobs will utilize PowerShell in different configurations.<\/p>\n<p>Executable<br \/>\nExecution Policy<br \/>\nPowerShell Version<\/p>\n<p>2008 R2 \u2013 PowerShell type<br \/>\nSQLPS.exe<br \/>\nRemoteSigned<br \/>\n2.0<\/p>\n<p>2008 R2 \u2013 CmdExec type<br \/>\npowershell.exe via cmd.exe<br \/>\nSystem Configured<br \/>\nLatest Installed<\/p>\n<p>2012 \u2013 PowerShell type<br \/>\nSQLPS.exe<br \/>\nRemoteSigned<br \/>\n2.0<\/p>\n<p>2012 \u2013 CmdExec type<br \/>\npowershell.exe via cmd.exe<br \/>\nSystem Configured<br \/>\nLatest Installed<\/p>\n<p>2014 \u2013 PowerShell type<br \/>\nSQLPS.exe<br \/>\nRemoteSigned<br \/>\n4.0<\/p>\n<p>2014 \u2013 CmdExec type<br \/>\npowershell.exe via cmd.exe<br \/>\nSystem Configured<br \/>\nLatest Installed<\/p>\n<hr \/>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/hammer-derik-172x140.png\" alt=\"\" \/><strong>Written by Derik Hammer of <a href=\"http:\/\/www.sqlhammer.com\/\">SQL Hammer<\/a><\/strong><\/p>\n<p>Derik is a data professional focusing on Microsoft SQL Server. His passion focuses around <a href=\"http:\/\/www.sqlhammer.com\/blog\/category\/high-availability\/\">high-availability<\/a>, <a href=\"http:\/\/www.sqlhammer.com\/blog\/category\/general\/disaster-recovery\/\">disaster recovery<\/a>, continuous integration, and automated maintenance. his experience has spanned long-term database administration, consulting, and\u00a0entrepreneurial ventures.<\/p>\n<p>Derik gives the SQL community credit for plugging the gaps in his knowledge when he was a junior DBA and, now that his skills have matured, started <a href=\"http:\/\/www.sqlhammer.com\/\">SQLHammer.com<\/a> as one small way to give back and continue the cycle of shared learning.<\/p>\n<p>Derik is the owner and lead author of SQL Hammer, a <a href=\"http:\/\/www.sqlhammer.com\/\">Microsoft SQL Server resource<\/a>.<\/p>\n<p>For more information, visit <a href=\"http:\/\/www.sqlhammer.com\/\">http:\/\/www.sqlhammer.com<\/a>. Follow Derik on <a href=\"http:\/\/twitter.com\/SQLHammer\">Twitter<\/a> for <strong>SQL tips and chat<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When creating a\u00a0SQL Agent Job to execute\u00a0a PowerShell script, you have to decide which way that you want the PowerShell to run. Depending upon which version of SQL Server that you are using and which job step type that you choose, you might be running in different versions of PowerShell with different execution policies. I [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-105","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/posts\/105","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/comments?post=105"}],"version-history":[{"count":1,"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/posts\/105\/revisions"}],"predecessor-version":[{"id":367,"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/posts\/105\/revisions\/367"}],"wp:attachment":[{"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/media?parent=105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/categories?post=105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sqlhammer.com\/index.php\/wp-json\/wp\/v2\/tags?post=105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}