Skip to content

Instantly share code, notes, and snippets.

View tcartwright's full-sized avatar

Tim Cartwright tcartwright

  • Houston, Texas
View GitHub Profile
@tcartwright
tcartwright / RebootServer.ps1
Created August 11, 2026 19:20
POWERSHELL: Reboot server at specific date and time (no scheduled task)
Clear-Host
$when = Get-Date -Date '2026-08-11 18:00'
$msg = 'Message about why reboot is happening'
if ($when -le (Get-Date)) { throw "21:00 has already passed on this host" }
$total = ($when - (Get-Date)).TotalSeconds
Write-Host ("Reboot armed for {0:yyyy-MM-dd HH:mm:ss} — leave this window open. Ctrl+C cancels." -f $when)
while ($true) {
@tcartwright
tcartwright / GetSQLStartupArguments.ps1
Created August 11, 2026 17:34
POWERSHELL: Get SQL Server command lines, and startup parameters
# Map friendly instance name -> registry key (e.g. RTR -> MSSQL16.RTR)
$instMap = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL'
Get-CimInstance Win32_Process -Filter "Name = 'sqlservr.exe'" | ForEach-Object {
$cmd = $_.CommandLine
$instName = if ($cmd -match '-s(\S+)') { $Matches[1] } else { 'MSSQLSERVER' }
$regKey = $instMap.$instName # e.g. MSSQL16.RTR
$regParams = @()
if ($regKey) {
@tcartwright
tcartwright / Sync-TimeFromInternet.ps1
Last active August 10, 2026 15:44
POWERSHELL: Sync Time From Internet: Gets the current UTC time from an internet time source and resets this machine's LOCAL clock to the correct current local time. It NEVER changes the time zone and NEVER touches the "adjust for DST automatically" switch.
<#
.SYNOPSIS
Sets this machine's clock to real internet time, correctly, on boxes where auto-DST is off.
.DESCRIPTION
Manual counterpart to timeset.cfm, for fixing a cycle server by hand - and the reference
implementation of the DST-safe conversion, because the obvious way to write it is wrong.
The trap
--------
@tcartwright
tcartwright / GetTLSSettings.ps1
Created August 3, 2026 14:36
POWERSHELL: Get a machines TLS settings
Clear-Host
function Def($v) { if ($null -ne $v) { $v } else { 'not set' } }
# Enabled TLS protocols (OS/SCHANNEL level)
'TLS 1.0','TLS 1.1','TLS 1.2','TLS 1.3' | ForEach-Object {
$p = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$_\Client"
$en = (Get-ItemProperty $p -Name Enabled -ErrorAction SilentlyContinue).Enabled
$dd = (Get-ItemProperty $p -Name DisabledByDefault -ErrorAction SilentlyContinue).DisabledByDefault
"{0,-8} Enabled={1} DisabledByDefault={2}" -f $_, (Def $en), (Def $dd)
@tcartwright
tcartwright / EnableRCSI.sql
Created July 16, 2026 02:23
SQL SERVER: Enable RCSI on server databases matching a prefix
/*==============================================================================
Enable READ_COMMITTED_SNAPSHOT (RCSI) for all databases matching a prefix
--------------------------------------------------------------------------
- Dry-run by default (prints the ALTER statements, changes nothing)
- Skips system DBs, snapshots, and any DB that is offline, read-only,
in standby, or already has RCSI on (idempotent)
- Requires EXCLUSIVE access per DB; @TerminationClause controls how it's
obtained. ROLLBACK IMMEDIATE disconnects other sessions and rolls back
their in-flight transactions.
==============================================================================*/
@tcartwright
tcartwright / CreateLoginPerEnvironment.sql
Last active August 7, 2026 14:46
SQL Server: Create login with different passwords per environments
/*==============================================================================
Provision / Rotate a Login by Environment + Grant Role in User DBs
------------------------------------------------------------------------------
Supports BOTH SQL logins and Windows logins/groups, selected via @LoginType.
1. (SQL only) Reads the 'environment' database extended property and selects
the password (shared across all pre-prod environments; a separate one for
prod). Windows logins have no password, so this step is skipped for them.
2. CREATEs the target login (if missing) or, for SQL logins, ALTERs its
password (if it already exists). Windows logins that already exist are a
@tcartwright
tcartwright / IISEnforceStandardLoggingFields.ps1
Created June 5, 2026 14:52
POWERSHELL: Enforce IIS standard logging fields
Clear-Host
#Requires -RunAsAdministrator
Import-Module WebAdministration -ErrorAction Stop
$apphost = "MACHINE/WEBROOT/APPHOST"
$standardFlags = "Date,Time,ClientIP,UserName,SiteName,ComputerName,ServerIP,Method,UriStem,UriQuery,HttpStatus,HttpSubStatus,Win32Status,BytesSent,BytesRecv,TimeTaken,ServerPort,UserAgent,Referer,ProtocolVersion,Host"
$customFields = @(
@{ name = "X-Forwarded-For"; src = "X-Forwarded-For"; type = "RequestHeader" }
@{ name = "Correlation-ID"; src = "X-Correlation-ID"; type = "RequestHeader" }
@tcartwright
tcartwright / CreateDefaultRoles.sql
Last active June 4, 2026 19:44
SQL SERVER: Create Default roles on all user databases
SET NOCOUNT ON;
DECLARE @DryRun bit = 1; -- 1 = print only, 0 = execute
-- Roles to ensure exist in every targeted database.
-- Permissions : granted to the role (raw permission list).
-- SchemaPattern : comma-delimited list of LIKE patterns matched against each DB's schemas.
-- Wildcards: % any string, _ any single char, [ ] char set/range.
-- Use \ to escape a literal wildcard (ESCAPE is set below). e.g. N'dbo'
-- or N'dbo,Reporting%' or N'%' (all user schemas).
@tcartwright
tcartwright / MapLoginToRoleOnUserDbs.sql
Last active July 8, 2026 14:54
SQL SERVER: Map login to all user databases except exclude list to role
SET NOCOUNT ON;
DECLARE @LoginName sysname = N'login-name';
DECLARE @RoleName sysname = N'db_datareader';
DECLARE @DryRun bit = 1; -- 1 = print only, 0 = execute
DECLARE @Excluded TABLE (DatabaseName sysname PRIMARY KEY);
INSERT INTO @Excluded (DatabaseName) VALUES
(N'master'),
@tcartwright
tcartwright / FindNonCluteredPKsWithClusteredIndex.sql
Created April 28, 2026 14:37
SQL SERVER: Find all non-clustered pks with a clustered index
/* ============================================================================
Find tables where the primary key is NONCLUSTERED but the table has a
separate CLUSTERED index (i.e. the clustering key is something other than
the PK).
For each matching table, returns:
- schema and table name
- the PK index name, its key columns, and any included columns
- the clustered index name, its key columns, and any included columns
(note: clustered indexes don't support INCLUDE at DDL time, so the