I was unable to cobble together some Powershell code that I could execute within a job-step to check our linked-servers were working.
So I resorted to making the best of the built-in, but flawed, “SP_testlinkedserver” (Its a flawed procedure as if a link fails, it crashes, slowly).
The code below, when ran in a job-step overnight, will dynamically create one job for each linked-server on the box. The job(s) will then run and email the “DBA” operator every linked-server that fails, before deleting themselves.
-- testlinkedservers.sql -- get list of all linked servers on this box CREATE TABLE #temp ( srv_name varchar(MAX), srv_providername varchar(MAX), srv_product varchar(MAX), srv_datasource varchar(MAX), srv_providerstring varchar(MAX), srv_location varchar(MAX), srv_cat varchar(MAX)) INSERT INTO #temp EXEC sp_linkedservers DELETE FROM #temp WHERE srv_name LIKE 'LOGSHIP%' DELETE FROM #temp WHERE srv_name = @@SERVERNAME -- loop DECLARE @name VARCHAR(MAX), @cmd VARCHAR(MAX), @run VARCHAR(MAX) WHILE (SELECT COUNT(*) FROM #temp) > 0 BEGIN SELECT TOP 1 @name = srv_name FROM #temp -- create the job code SET @cmd = 'BEGIN TRANSACTION DECLARE @jobId BINARY(16) SELECT @jobId = job_id FROM msdb.dbo.sysjobs WHERE (name = N''DBA - LinkedServerTest ' + @name + ''') IF (@jobId IS NULL) BEGIN EXEC msdb.dbo.sp_add_job @job_name=N''DBA - LinkedServerTest ' + @name + ''', @enabled=1, @notify_level_eventlog=2, @notify_level_email=2, @notify_level_netsend=0, @notify_level_page=0, @delete_level=3, @description=N''No description available.'', @category_name=N''[Uncategorized (Local)]'', @owner_login_name=N''sa'', @notify_email_operator_name=N''DBA'', @job_id = @jobId OUTPUT END -- create the job-step code IF NOT EXISTS (SELECT * FROM msdb.dbo.sysjobsteps WHERE job_id = @jobId AND step_id = 1) EXEC msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N''one'', @step_id=1, @cmdexec_success_code=0, @on_success_action=1, @on_success_step_id=0, @on_fail_action=2, @on_fail_step_id=0, @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N''TSQL'', @command=N''sp_testlinkedserver [' + @name + ']'', @database_name=N''master'', @flags=0; -- create instantiation code EXEC msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N''(local)'' COMMIT TRANSACTION' -- create the job EXEC(@cmd) -- run the job SET @run = 'EXECUTE msdb.dbo.sp_start_job ''DBA - LinkedServerTest ' + @name + '''' EXEC(@run) -- move to next row in loop DELETE FROM #temp WHERE srv_name = @name END
.