Skip to content

Instantly share code, notes, and snippets.

View ghotz's full-sized avatar

Gianluca Hotz ghotz

View GitHub Profile
@ghotz
ghotz / evaluate-recovery-time.sql
Created May 8, 2024 10:01
Evaluate and standardize database recovery time
SELECT
[name] AS database_name, target_recovery_time_in_seconds
, CASE
WHEN target_recovery_time_in_seconds = 60
THEN NULL
ELSE 'ALTER DATABASE [' + [name] + ']'
+ ' SET TARGET_RECOVERY_TIME = 60 SECONDS;'
END AS alter_command
FROM sys.databases
WHERE [name] NOT IN ('master','model','msdb','tempdb')
@ghotz
ghotz / view-ag-listener-details.sql
Created May 8, 2024 08:06
Various Availability Groups metadata queries
SELECT AG1.[name] AS ag_name
, AL1.dns_name AS ag_listener_dns_name
, AL1.[port] AS ag_listener_tcp_port
, AL2.ip_address AS ag_listener_ip_address
, AL2.ip_subnet_mask AS ag_listener_ip_subnet_mask
FROM sys.availability_groups AS AG1
JOIN sys.availability_group_listeners AS AL1
ON AG1.group_id = AL1.group_id
JOIN sys.availability_group_listener_ip_addresses AS AL2
ON AL1.listener_id = AL2.listener_id
@ghotz
ghotz / auto-deny.ps1
Last active October 22, 2024 14:57
Auto ban IP subnets by POST requests total size over a certain threshold in the last http log file
#region startup
# Warning: remember to whitelist who you want to allow to post by entering their IP addresses in the Azure Portal
#import-module Az;
$TenantID = 'YOURTENANTID';
$SubscriptionID = 'YOURSUBID'
$ResourceGroupName = 'WebSite';
$AppServiceName = 'YOURSERVICENAME';
$MyIP = (Invoke-WebRequest -uri "http://ifconfig.me/ip").Content; #avoid self-banning
$MaxPostsBytes = 100KB;
$SubnetSize = 30; # adjust as needed
@ghotz
ghotz / get-top-by-bytes-in.ps1
Created May 3, 2024 04:50
Analyze Azure App Service Log Files in Kudu Console
$MyIp = 'xxx.xxx.xxx.xxx';
$Log = Get-Content "C:\home\logfiles\http\rawlogs\*.log" | Select -Skip 2 | ConvertFrom-Csv -Delimiter " " -Header 'date','time','s-sitename','cs-method','cs-uri-stem','cs-uri-query','s-port,cs-username','c-ip','cs(User-Agent)','cs(Cookie)','cs(Referer)','cs-host','sc-status','sc-substatus','sc-win32-status','sc-bytes','cs-bytes','time-taken';
$Log | ? { $_.'cs-method' -eq 'POST' -and $_.'cs(User-Agent)' -ne $MyIp } | Group-object -Property 'cs(User-Agent)' | % {[pscustomobject]@{Type=$_.Name;'Total POSTs'=$_.Count;'Total Bytes ↓' = ($_.group | measure-object 'cs-bytes' -Sum).Sum}} | Sort-Object 'Total Bytes ↓' -Descending | Select -first 10 | ft;
@ghotz
ghotz / get-http-rawlogs-top-offenders.ps1
Created April 22, 2024 12:00
Get top 10 offenders IP for total POSTS count and bytes from http logfiles
$Log = Get-Content "C:\home\logfiles\http\rawlogs\*.log" | Select -Skip 2 | ConvertFrom-Csv -Delimiter " " -Header 'date','time','s-sitename','cs-method','cs-uri-stem','cs-uri-query','s-port,cs-username','c-ip','cs(User-Agent)','cs(Cookie)','cs(Referer)','cs-host','sc-status','sc-substatus','sc-win32-status','sc-bytes','cs-bytes','time-taken';
$Log | ? { $_.'cs-method' -eq 'POST' } | Group-object -Property 'cs(User-Agent)' | % {[pscustomobject]@{Type=$_.Name;'Total POSTs ↓'=$_.Count;'Total Bytes' = ($_.group | measure-object 'cs-bytes' -Sum).Sum}} | Sort-Object 'Total POSTs ↓' -Descending | Select -first 10 | ft
$Log | ? { $_.'cs-method' -eq 'POST' } | Group-object -Property 'cs(User-Agent)' | % {[pscustomobject]@{Type=$_.Name;'Total POSTs'=$_.Count;'Total Bytes ↓' = ($_.group | measure-object 'cs-bytes' -Sum).Sum}} | Sort-Object 'Total Bytes ↓' -Descending | Select -first 10 | ft
@ghotz
ghotz / get-space-multiple-tables.sql
Last active February 13, 2024 11:04
Get tables/indexes space usage
-- based on https://stackoverflow.com/questions/7892334/get-size-of-all-tables-in-database/64037173#64037173
DECLARE @tables TABLE (table_name sysname primary key);
INSERT @tables VALUES ('schemaname.tablename'), ('schemaname.tablename')
SELECT
[object_id] = t.[object_id]
,[schema_name] = s.[name]
,[table_name] = t.[name]
,[index_name] = CASE WHEN i.[type] in (0,1,5) THEN null ELSE i.[name] END -- 0=Heap; 1=Clustered; 5=Clustered Columnstore
,[object_type] = CASE WHEN i.[type] in (0,1,5) THEN 'TABLE' ELSE 'INDEX' END
@ghotz
ghotz / session-wait-stats-percentages.sql
Created November 19, 2023 11:18
Calculates individual wait stats weight on total waits for a given session
WITH cte_total_session_waits AS
(
SELECT [session_id]
, SUM(waiting_tasks_count) AS waiting_tasks_count
, SUM(wait_time_ms) AS wait_time_ms
, MAX(max_wait_time_ms) AS max_wait_time_ms
, SUM(signal_wait_time_ms) AS signal_wait_time_ms
FROM sys.dm_exec_session_wait_stats
GROUP BY [session_id]
)
@ghotz
ghotz / daily-check-high-privileges.sql
Created November 16, 2023 17:54
Sends a daily report with all user members of the sysadmin role or having ALTER ANY SERVER ROLE, CONTROL SERVER permissions
DECLARE @MailProfile sysname = N'';
DECLARE @AgentOperator sysname = '';
DECLARE @MailRecipients nvarchar(max) = (select email_address from msdb..sysoperators WHERE [name] = @AgentOperator);
DECLARE @MailSubject nvarchar(max) = N'Daily users with high privileges on server ' + @@SERVERNAME;
DECLARE @MailQueryTable nvarchar(max) =
N'<h1>Daily users with high privileges on server ' + @@SERVERNAME + N' report</h1>'
+ N'<table border="1">'
+ N'<tr><th>Instance Name</th><th>Login Name</th><th>Login Type</th><th>Creation Date</th><th>Permission Type</th></tr>'
+ CAST((
SELECT
@ghotz
ghotz / switch-cdc-jobs.sql
Created November 16, 2023 15:38
Switch CDC jobs by stopping, enabling and disabling them based on current AG replica role. To be called as response to state change alerts.
DECLARE @sqlstmts nvarchar(max);
WITH cte_sqlstmts AS
(
SELECT
N'exec msdb.dbo.sp_stop_job @job_name = ''' + [name] + N'''; ' AS sqlstmt
FROM msdb.dbo.cdc_jobs AS J1
JOIN msdb.dbo.sysjobs_view AS J2
ON J1.job_id = J2.job_id
JOIN msdb.dbo.sysjobactivity AS A1
@ghotz
ghotz / online-rebuild-all-tables-indexes.sql
Last active November 14, 2023 15:00
Online rebuild all tables and indexes (partition and lob aware)
SELECT
CASE
WHEN I1.[type_desc] IN ('HEAP', 'CLUSTERED')
THEN 'ALTER TABLE [' + S1.[name] + '].[' + O1.[name] + ']'
WHEN I1.[type_desc] = 'NONCLUSTERED'
THEN 'ALTER INDEX [' + I1.[name] + '] ON [' + S1.[name] + '].[' + O1.[name] + ']'
END
+ ' REBUILD' +
CASE
WHEN EXISTS (SELECT * FROM sys.partitions AS P2 WHERE P1.[object_id] = P2.[object_id] AND P1.[index_id] = P2.[index_id] AND P2.partition_number > 1)