Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

At my new job, we have multiple named instances on each servers.

  • Server1\Dev
  • Server1\DevIntegrated
  • Server1\QA

I have a SQL PowerShell script in the works that calls out to the OS, invokes Foo.exe but needs to pass a command line parameter (the connection string). A SQL Agent job will exist on each instance, with a step of type PowerShell, that needs to know what the current context is. i.e. This execution began on DevIntegrated.

I have no desire to have every script start with

$thisInstance = "Dev"

eespecially as I'd have to edit that as we migrate to environments (new servers and named instances) in the upcoming months.

If I start SQLPS, I can determine my instance by slicing and dicing the results of Get-Location or running

(Invoke-Sqlcmd -Query "SELECT @@servername AS ServerName" -SuppressProviderContextWarning).ServerName

When the SQL Agent starts a job of type PowerShell, it starts in the C:\windows\system32 The Get-Location route doesn't work as it's not in the SQLSERVER context. I can change into that context but I'll be at the "root" of SQL Server and won't know what instance I should be in. Using the Invoke-Sqlcmd route won't work either for same reason (technically, it times out as there is no default instance)

To the best of my knowledge, I've enumerated all the basic "things" I can Get into the job log but nothing seems to show SQLSERVER:\SQL\Server1\DevIntegrated

  • Get-ChildItem
  • Get-Host
  • Get-Location
  • Get-Process
  • Get-PSDrive
  • Get-PSProvider
  • Get-Service
  • Get-TraceSource
  • Get-Variable

Get-Process seems like I could use that and some voodoo of trying to cobble things together by hitting the instances and matching spids but that just sounds like a bloody-hack from hell. There must be something basic that I'm missing, can anyone shed some light?

Alternatives to PowerShell investigated

I had investigated using other job types and didn't get a satisfactory resolution. Research indicated the PowerShell listed under SQL Agent was SQLPS and starting an instance of it by right clicking on the Agent automagically dropped me into the correct location. It was only when I pasted my interactive code into the job step that I learned of the difference as previously mentioned.

Job type of OS put me into an identical state in that I could not find a way to determine which instance dropped me into the command shell. Sure, I could sqlcmd and get the value of @@servername but if I knew what connection to start sqlcmd, I wouldn't need to to query the database ;)

TSQL could probably work if we enable xp cmdshell but I'm not sure if they have it turned on---government facility and they can be persnickety on non-default settings. Even then, I'm stuck futzing with dynamic SQL and losing a lot of the expressiveness and power that PowerShell lends.

While a bit ungainly, I thought defining a variable at the first step and passing that to successor steps but research turned up this article Handling Multiple Job Steps (BOL)

"Job steps must be atomic. A job cannot pass Boolean values, data, or numeric values between job steps. You can pass values from one Transact-SQL job step to another by using permanent tables or global temporary tables. You can pass values from one CmdExec job step to another by using files."

I can't use common tricks like a well-known file/environment variables/registry setting that Foo.exe looks for as that would prevent concurrent execution across instances.

tl;dr

In a SQL Agent Job step of type PowerShell, how can you determine the instance of SQL Server that launched the process?

share|improve this question
4  
Is powershell a requirement for what you are doing? –  John DaCosta Jun 25 '11 at 6:23
    
The true requirement would be to have a reuasble "something" in SQL agent that can launch a DOS process with a parameter of the invoking instance. PowerShell seemed the best fit given what didn't work above. Sorry for tardy response, I was out at Scout camp. –  billinkc Jun 30 '11 at 12:00
add comment

2 Answers

If you look in SQL Server BOL, SQL Server Agent provides a set of "tokens" that it will substitute into both the job step command text and the output file (the later will prevent the GUI "view" button from working). These tokens seem to work for any type of step except T-SQL.

http://msdn.microsoft.com/en-us/library/ms175575.aspx

So, if you have a SQL 2008 PowerShell step, you can start it with:

$sqlInstance = "$(ESCAPE_DQUOTE(SRVR))"

You may need to use MACH (machine name) and INST (just instance name) instead, because with the default instance SRVR == MACH, but with named instances SRVR == MACH\INST.

share|improve this answer
    
Nice work David. –  jcolebrand Oct 22 '11 at 0:35
add comment

Sad to say I have not done much with PowerShell scripts being called inside SQL Server. Nor am I at a computer that I could play with it right now.

I believe though instead of using the PowerShell type step that if you used CmdExec and just call your script as you would from a command line "powershell 'MyScript.ps1'" you could then pass a parameter that has the instance you are running from. Like "Powershell 'MyScript.ps1' MyInstanceName".

So the start of your script you have a param() setup to accept that value of MyInstanceName:


param(
   [Parameter(Position=0,Mandatory=$True)]
   [string]$InstanceName
)
#so if I wanted to use sqlcmd
sqlcmd -S $InstanceName -Q "SELECT @@VERSION"

As you started out stating the one step needed to know what instance it was on so the PowerShell script could call Foo.exe properly. However, later on you mention being able to pass the value to other steps. If this is true you might want to look at creating a small SSIS package that calls your PowerShell script and does whatever else you need. With SSIS you could be able to setup a global variable that the whole package could use.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.