Use of variable issue

  • All,

    I'm trying to set up some code in a SQL agent job.

    The following code works as expected:

    $sqlConn = New-Object System.Data.SqlClient.SqlConnection
    $sqlConn.ConnectionString = ""
    $sqlcommand = $sqlConn.CreateCommand()
    $sqlcommand.CommandText="Select filename from dbo.ssisfiles"
    $DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
    $dataset = new-object System.Data.Dataset
    $DataAdapter.Fill($dataset)
    foreach ($Row in $dataset.Tables[0].Rows)
    {
    if (Test-Path -Path "c:\as_demo.txt")
    {
    Throw "File exists"
    }
    }

    If the file c:\as_demo.txt exists the error is thrown. I'm trying to do the same thing with a variable but without success. I've tried several variations. My current version is:

    $sqlConn = New-Object System.Data.SqlClient.SqlConnection
    $sqlConn.ConnectionString = ""
    $sqlcommand = $sqlConn.CreateCommand()
    $sqlcommand.CommandText="Select filename from dbo.ssisfiles"
    $DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
    $dataset = new-object System.Data.Dataset
    $DataAdapter.Fill($dataset)
    foreach ($Row in $dataset.Tables[0].Rows)
    {
    if (Test-Path -Path "$Row[0]")
    {
    Throw "File exists"
    }
    }

    That gives the error:'SQL Server PowerShell provider error: Path SQLSERVER:\System.Data.DataRow[0] does not exist. Please specify a valid path. '. Process Exit Code 0. The step succeeded.

    Can anyone advise the correct syntax for using a variable?

    The connectionstring and commandtext values are not blank in my testing, I just removed them from the code above.

    Thanks

     

    • This topic was modified 7 months, 3 weeks ago by  as_1234.
    • This topic was modified 7 months, 3 weeks ago by  as_1234. Reason: Added in the commandtext
  • Path is not passed is it the intention to use a local drive as it’s not specified clearly in the 2nd script.

    Bit more info on what it is you’re trying to achieve would help, what does the data from the row look like

    -----------------------------------------------------------------------------------------------------------

    "Ya can't make an omelette without breaking just a few eggs" 😉

  • Hello,

    Thanks for your help.

    Apologies I didn't mean to be vague. I've now added the commandtext to my original post. At the moment the table has one row and the filename value is 'c:\as_demo.txt'.

    What I'm trying to do is get the script to get a list of files from the database and throw an error if any of them exists.

    I think in my second script above it's taking $Row[0] literally and not changing it to c:\as_demo.txt? If so I can't work out how to make it use the variable value instead of the name.

  • if   (Test-Path -Path  "$($Row)")
    {
    Throw "File exists"
    }

    -----------------------------------------------------------------------------------------------------------

    "Ya can't make an omelette without breaking just a few eggs" 😉

  • Thanks for your help. That gives me the error:

    Message

    Unable to start execution of step 1 (reason: line(10): Syntax error). The step failed.

    This is the code:

    $sqlConn = New-Object System.Data.SqlClient.SqlConnection
    $sqlConn.ConnectionString = ""
    $sqlcommand = $sqlConn.CreateCommand()
    $sqlcommand.CommandText="Select Filename from dbo.SSISFiles"
    $DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
    $dataset = new-object System.Data.Dataset
    $DataAdapter.Fill($dataset)
    foreach ($Row in $dataset.Tables[0].Rows)
    {
    if (Test-Path -Path "$($Row)")
    {
    Throw "File exists"
    }
    }

    I'll continue seeing if I can work it out.

  • Comment out the if block and try printing the contents of the $Row var see what’s inside it

    -----------------------------------------------------------------------------------------------------------

    "Ya can't make an omelette without breaking just a few eggs" 😉

  • The problem here is the $ in the PS script.  SQL Server Agent is attempting to use that as a token - and that is causing the failure.  The only way to resolve that is to create a PS file (e.g. command.ps1) and call that from the agent.

    You could try disabling token replacement - but that will disable it for all agent jobs.

    Jeffrey Williams
    “We are all faced with a series of great opportunities brilliantly disguised as impossible situations.”

    ― Charles R. Swindoll

    How to post questions to get better answers faster
    Managing Transaction Logs

  • All,

    Thanks for your help.

    I think I may have just got it working with:

       if   (Test-Path -Path  $Row.Item(0))
    {
    Throw "File exists"
    }
    }

    I'm still testing. I'll post later to confirm whether it works or not.

  • just noticed this was part of a SQL Agent step.

    word of advise - NEVER EVER use powershell directly on a step - either code it in C# on a SSIS package or create a powershell script and execute it from the step (cmd exec best option for me, but executing a script also possible from a PS step - but again avoid this last one)

  • Thanks for the advise.

    If you don't mind me asking - why do you advise that? I'm not disagreeing, I'm asking because I'm new to Powershell and interested to learn.

    I think using the cmd exec option means xp_cmdshell needs to be enabled?

     

  • as_1234 wrote:

    Thanks for the advise.

    If you don't mind me asking - why do you advise that? I'm not disagreeing, I'm asking because I'm new to Powershell and interested to learn.

    I think using the cmd exec option means xp_cmdshell needs to be enabled?

    powershell step on SQL Agent does not execute the standard powershell but rather a SQL one which has a few differences- and as mentioned above SQL Agent uses tokens which can affect the code you do.

    the cmd exec is just the standard SQL Agent step of  type "Operating system (cmdexec)" - it does not require enabling xp_cmdshell.

  • Aside what Fredrico stated, setup a credential and proxy for the agent job step exec type and run the job step under the proxy ensuring it has permissions granted where required

    -----------------------------------------------------------------------------------------------------------

    "Ya can't make an omelette without breaking just a few eggs" 😉

  • All,

    Thanks for your advise. I'll change to using Operating system (cmdexec).

Viewing 13 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic. Login to reply