Friday, April 21, 2017

[Powershell] Run powershell code 30 seconds after the job it's in finishes(!)

We have a process that, when it fails, has a tracking table, and as each step is run it updates that row in the tracking table.  If the job fails, we know in which step it failed.

I also have a process that looks at failed jobs every minute, and sends out the tracking table info when a SSISDB job fails, so we get a useful message.  (See SSISDB in this blog).

However, the tracking table means that a job will wait to be fixed.  I don't want to update it as part of the job, since then I can't get the state of the tracking table. So what I need is either to kick off another job that waits 2 minutes... or use powershell.  :)

Next up is feeding it a parameter, and setting the background script to use an update statement

Note: works in powershell 2 or greater.  This seems much easier to do in newer versions.

First script "runinforeground.ps1":
start-process -filepath "powershell" -argumentlist "c:\temp\runinbackground.ps1"

Second Script "RunInBackground.ps1":
$now = get-date
start-sleep -s 10
$now | out-file c:\temp\whatisnow.txt #here is where I'd do the invoke-sqlcmd2 and the update

SQL Server Agent Job Step (CmdExec):
powershell.exe "c:\temp\runinforeground.ps1"

Wednesday, March 22, 2017

[Event Notifications] CONNECT and SQL permissions between boxes.

Just ran into this and didn't have it blogged for some reason.

For Event Notifications, you need two permissions on the monitorING server, for the service account running on the monitorED server.  First, there's SQL.  Second, there's Endpoint.  It must have both.

If you just have CONNECT SQL enabled, not the endpoint, then what I saw in sys.transmission_queue was:

An error occurred while receiving data: '24(The program issued a command but the command length is incorrect.)'.

Here's the command to grant it.  Remember that the authorization will be the name you're logged in as, so you might change that or ALTER the AUTHORIZATION afterwards (see

use [master]
GRANT CONNECT ON ENDPOINT::[ENAudit_Endpoint] TO [yourdomain\monitorEDserviceacct]

Wednesday, March 1, 2017

[Event Notifications] SQL 2016 and a new exclusion

We just rolled a bunch of servers to SQL Server 2016, and we're now getting this in our event log, once every 5 minutes, for each server.  On the plus side, I didn't know about telemetry_xevents before, and it looks like a nice new tool to query.  However, I don't need these.

Here's how to prevent them from showing up.  Super-simple exclusion.

INSERT INTO ENAudit_Exclusion_List
VALUES  ('aw', -- exclusion_set - char(2)
         'ObjectName', -- exclusion_type - varchar(128)
         'telemetry_xevents', -- excluded_value - varchar(128)
         GETDATE(), -- insert_datetime - datetime
         null, -- update_datetime - datetime
         1  -- active - bit

Thursday, February 16, 2017

[Forthcoming] Doing it wrong - Hekaton.

Okay, I've got an idea for a series of blog posts.  I've recently implemented In-Memory OLTP (IMOLTP, which I will now start pronouncing Im-Ho-Tep), and learned a bunch in a short period of time.  Don't do it like me.  Do it better.

Many thanks to Ned Otter for helping out a ton during this time.

Create in-memory FG
Create in-memory table
Create second in-memory FG
Create/destroy to new name
Stored procedure not working - still needs to only be in THAT database. No cross-DB work in SPs!
Resource issues!  (show event log)
Missing inserts copying from _live to _main? Why? (all about the COMMITs)
Answer: flip the order we get the IDs.
Pare down for now so we don’t run out of memory
DBCC caused problems with memory
Identity value on both table – have to monitor
Resource governor to the rescue?
 (I did this part, but remember to take the DB offline/online and sweat while it takes forever to come up)
Rebalance the In-memory filegroups if you have older data in there!

[Powershell] scripting out a servers via Red-Gate's SQL Compare

Grant Fritchey posted a basic powershell script that uses Red-Gate's SQL Compare to script out a database (  When I did it, it skipped partitioning and compression, so I wanted to put down my actual script somewhere for the next time I need this.  Specifically, "/options:none", so everything gets included.

Now that I've done it, I'm looking at the resulting folder structure - which doesn't match the structure I already have in place, using a different script (PoSH + SMO).  But I've written it, so here you go.

set-Location "c:\Program Files (x86)\Red Gate\SQL Compare 12\";
. C:\powershell_scripts\invoke-sqlcmd2.ps1

$Servers = "ser-ver-a","ser-ver-b"
$Path = "C:\temp\decom_server_scripting_via_redgate"

foreach ($server in $servers){
Invoke-Sqlcmd2 -Query "sp_databases" -ServerInstance $Server | ForEach-Object {Invoke-Expression "./sqlcompare.exe /s1:$Server /db1:$($_.DATABASE_NAME) /mkscr:$($Path)\$($Server)\$($_.DATABASE_NAME) /options:none" }

Thursday, January 19, 2017

[SSRS] Replacing an image embedded in the report with a new one via RDL manipulation.

Quick and Dirty:

I had a report, and had to change the logo to the new&improved version.  Didn't want to actually TOUCH anything within the report, lest I break it. The person who designed it had the image embedded within the report - please don't do that, but instead reference a file or fileshare or something. (makes replacing it much easier, but then you have to make sure where the images are is "safe" and Highly Available)

Step 1: download the RDL

Step 2: open in Notepad.

Looking near the top...

Okay, this is somewhat human-readable. Figure out which image it is.  Mine was simple - only one image, 2 inches wide by 1 inch tall.  Now let's find the actual image.

Okay, that's cool.  It's a PNG file, via MIME (base64) encoding.  Let's see what it looks like.
Take everything within ImageData, copy it, and go to:

Paste, and convert.  Verify it's the right image. Yup!

Now what? Get a new image about the same size (so it'll fit when scaled - let's not touch things if we can avoid it).  Save as PNG, even.  Now go back to that askapache, and upload it.  Copy the RAW out, and refresh the page.  Paste it back in and make sure it's showing what you expect (aka the new image). 

Finally, take this new string, replace ImageData with it, save the new version, then upload->replace the RDL. Test and done!