· Uwe Janke
Commands / Install-sqmStandardJob

Install-sqmStandardJob

Always OnsqmSQLTool v1.9.168+ · New🔓 SQLAgentOperatorRole / sysadmin on the job instance
Recurring tasks that every AlwaysOn installation needs are kept in a small catalog: target function, safe parameter defaults, job name and schedule. One call turns a catalog entry into a SQL Server Agent job, no parameter hashtables needed. The job is built by New-sqmAgentCommandJob (generic CmdExec wrapper with typed .clixml parameters). -List shows the catalog.

NameRunsDefaults
AgLoginSyncSync-sqmLoginsToAlwaysOn-Force:$false, daily 02:00, job sqmAutoLoginSync
AgLoginCompareCompare-sqmAlwaysOnLogins-FailOnDrift -OnlyDifferences, daily 06:00, job sqmAutoLoginCompare

Install the AG jobs on every replica. They are PrimaryOnly: the job step first checks the local AG role and, on a secondary, ends with success without calling the function. After a failover the new primary simply takes over and no job turns red.

Why the login sync runs without -Force. -Force replaces existing logins by DROP and CREATE. If the CREATE fails afterwards (policy, transient error, AD latency) the login is gone on the secondary, which happened in unattended runs. The standard job therefore only adds missing logins and warns if you force Force = $true through -Parameters. Password or default database drift is reported by AgLoginCompare and fixed deliberately by hand.

Parameters

ParameterTypeRequiredDefaultNotes
-NamestringRequired, Catalog entry: AgLoginSync or AgLoginCompare.
-ListswitchSwitch$falseShow the catalog with all defaults instead of installing anything.
-SqlInstancestringOptional$env:COMPUTERNAMEInstance where the job is created. Run the function on that machine, the wrapper files are written locally.
-SqlCredentialPSCredentialOptional, Only for the connection that creates the job. The step runs as the SQL Agent service account, which needs sysadmin on all replicas.
-AvailabilityGroupNamestringOptionalfirst AGAG for the AG jobs. Also narrows the PrimaryOnly check to that AG.
-JobNamestringOptionalfrom catalogOverride the job name.
-ParametershashtableOptional, Merged over the catalog parameters, your values win. Example: @{ AuditAdOrphans = $true }.
-ScheduleTypestringOptionalfrom catalogNone, Daily, Weekly or Monthly.
-ScheduleTimestring HH:mmOptionalfrom catalogStart time of the schedule.
-ScheduleDaysstring[]Optional, Weekdays for -ScheduleType Weekly.
-ForceswitchSwitch$falseReplace an existing job of the same name.
-StartJobswitchSwitch$falseRun the job once immediately after creating it.
-EnableExceptionswitchSwitch$falseThrow exceptions immediately instead of returning a result object with Status Failed.
-WhatIf / -ConfirmswitchSwitchConfirmImpact = MediumShow or confirm the installation before anything is written.

Execution Flow

START -List? YES Return the catalog Nothing is created NO Build the step parameters Catalog defaults, then SqlInstance and AvailabilityGroupName, then -Parameters (wins) AgLoginSync with Force = $true: warning about DROP + CREATE New-sqmAgentCommandJob CmdExec step: generic wrapper + typed .clixml file, flagged -PrimaryOnly Schedule from the catalog or your override, -Force replaces, -StartJob runs once At every job run The wrapper asks sys.dm_hadr_availability_replica_states for the local role first Local replica primary? NO Step ends with success Function is not called YES Run the catalog function Sync-sqmLoginsToAlwaysOn or Compare-sqmAlwaysOnLogins with the stored parameters DONE

Return Value

PSCustomObject with Name, SqlInstance, JobName, FunctionName, Parameters, ScheduleName, PrimaryOnly, Started, Status (Success or Failed), Message, Timestamp. With -List: one object per catalog entry.

Examples

Show the catalog with all defaults
Install-sqmStandardJob -List
Login sync on every replica of the AG (run on each node)
Install-sqmStandardJob -Name AgLoginSync -AvailabilityGroupName 'AG_Prod'
Also report Windows logins without an AD account (detection only)
Install-sqmStandardJob -Name AgLoginSync -AvailabilityGroupName 'AG_Prod' -Parameters @{ AuditAdOrphans = $true } -Force
Drift alarm: the job fails when logins differ between replicas
Install-sqmStandardJob -Name AgLoginCompare -AvailabilityGroupName 'AG_Prod' -ScheduleTime '07:30'