Category Archives: PowerShell

Invoke-SqlCmd throws exception when trying to set the database via parameter

This was properly doing my nut today! Basically I created a generic script to fix orphaned users and replaced the database with the standard SqlCmd variable syntax:

use $(DatabaseName);

When running in SSMS setting the variables like this:

:setvar DatabaseName MyDatabase

works fine, as it does when setting as a param to the sqlcmd.exe:

sqlcmd -i C:\PathToScript.sql -v DatabaseName=MyDatabase

however when using the PowerShell Invoke-SqlCmd Cmdlet from the SqlServer PowerShell extensions it throws an exception that gives you absolutely no clue as to why:

Invoke-Sqlcmd : Object reference not set to an instance of an object.
At C:\Users\mayesr\Desktop\PowerShellScratchPad.ps1:22 char:14
+ Invoke-Sqlcmd <<<< -InputFile "$g_ScriptLocation\FixUser.sql" -ServerInstance "localhost" -Verbose + CategoryInfo : InvalidResult: (localhost:PSObject) [Invoke-Sqlcmd], NullReferenceExcep tion + FullyQualifiedErrorId : ExecutionFailed,Microsoft.SqlServer.Management.PowerShell.GetScriptComm and

I eventually noticed that the Invoke-SqlCmd has a parameter that you can set the database with. Once that was set and the use statement removed, the script worked fine! Luckily it didn’t take me too long to notice but hopefully if you come across this post it will save you some time!!

UPDATE

After I thought I had fixed this I realised that it wasn’t the Database param at all and in-fact was any param! I eventually found out there is a bug in the MSDN docs (and/or code)!! The docs say that the following format should be used:

$MyArray = "MyVar1 = 'String1'", "MyVar2 = 'String2'"
Invoke-Sqlcmd -Query "SELECT `$(MyVar1) AS Var1, `$(MyVar2) AS Var2;" -Variable $MyArray

However this doesn’t work and the following should be used instead (remove the spaces around the ‘=’):

$MyArray = "MyVar1='String1'", "MyVar2='String2'"
Invoke-Sqlcmd -Query "SELECT `$(MyVar1) AS Var1, `$(MyVar2) AS Var2;" -Variable $MyArray

I just wish I’d scrolled down to the bottom of the page as other people had added comments saying this!! 😡

Using PowerShell to record ping failures to a logfile

Recently we’ve been having some major problems with our websites not being able to connect to our Sql2008 cluster. Part of the analysis I was asked to run (yes I do seem to do everything here!!) was a simple ping test. We started off with the classic command line ping to file using the pipeline (ping IPADDRESS -t > LogFile.txt). This is good but has one major flaw, the results don’t record the date and time to file, all you can see is that it DID fail. So I decided to use my favourite scripting language to knock up something a bit better and this is what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$serverName = "[IpAddress]";
$showAllResults = $false;
$logFilename = "[PathToLogFile]";
$ping = new-object Net.NetworkInformation.Ping;
$minRoundTripTime = 500;

function WriteToOutput($filename, $text)
{
    $text | Out-File $filename -Append;
    Write-Host $text;
}

WriteToOutput $logFilename "$(Get-Date): Starting ping logging...`nPress any key to stop!";

do
{
    $result = $ping.send($serverName);
    if($showAllResults -or $result.Status -ne "Success" -or $result.RoundtripTime -gt $minRoundTripTime)
    {          
        WriteToOutput $logFilename  "$(Get-Date) -Status: $($result.Status) -time: $($result.RoundTripTime)`n";
    }
}
until ($Host.UI.RawUI.KeyAvailable);

WriteToOutput $logFilename "$(Get-Date): Ending ping logging...`n`n";

Let me know if you have any suggestions to improve it!! 🙂

Killing database connections with PowerShell

Recently I have been setting up a PowerShell script to automatically setup our PY (usually aka SIT) environment. One of the tasks in the script is to Kill all the connections to a database so I can restore a backup. I managed to find a function that met my needs using the SMO libraries. Unfortunately as we are still on Sql2000 (I know, I know! Its not for much longer now tho! 😀 ) the SMO Libraries were not available on our database server so I had to come up with an alternative. Basically I decided to go the route that required the least dependancies and this is what I came up with!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function KillDBConnections([string]$serverName, [string]$DBName)
{
    $ConnectionString = "Data Source=$serverName;Initial Catalog=master;Integrated Security=SSPI"
    $connection = New-Object System.Data.SqlClient.SqlConnection($ConnectionString);
    $command = New-Object System.Data.SqlClient.SqlCommand;

    $command.Connection = $connection;
    $command.CommandType = [System.Data.CommandType]::Text;
    $command.CommandText = "SELECT spid FROM master..sysprocesses WHERE dbid=db_id('$DBName')";

    $connection.open();
    $reader = $command.ExecuteReader();
    $stringBuilder = New-Object System.Text.StringBuilder

    while ($reader.Read())
    {
        $stringBuilder.AppendFormat("kill {0};", $reader.GetValue(0));
    }

    $reader.Close();

    $command.CommandText = $stringBuilder.ToString();

    if($command.CommandText)
    {
        $command.ExecuteNonQuery();
    }
   
    $connection.Dispose();
}