Skip to content
Stam, Marcel edited this page Sep 9, 2026 · 8 revisions

PublicScripts Wiki

A collection of reusable PowerShell and T-SQL scripts for enterprise Active Directory, SQL Server, and infrastructure management.


Contents


Getting Started

  1. Clone or download the repository.
  2. Navigate to the folder of the script you need.
  3. Read the accompanying .md file for full prerequisites, parameters, and examples.
  4. Run from an elevated PowerShell session where required (noted per script).

All PowerShell scripts require PowerShell 5.1 or PowerShell 7+ unless stated otherwise. T-SQL scripts require SQL Server 2016 or later.


Scripts

Add-Named-Instances

Version 2.0.0 | PowerShell | Requires local administrator | CIS hardening

Assigns NT Service\<ServiceName> virtual accounts for SQL Server named instance services (engine, agent, SSIS) to the local security groups that correspond to the Windows User Rights Assignments required by CIS hardening guidelines.

What it does Detail
Discovers services Get-Service (SQL engine / agent) + Get-CimInstance Win32_Service (SSIS / all NT Service accounts)
Creates groups Missing local security groups are created automatically
Verifies LSA rights Exports effective policy via secedit /export and logs any gaps between group membership and User Rights Assignment
Safe to re-run Idempotent — already-present members are skipped
Dry run Full -WhatIf support; log is still written
Exit code 1 when any operation fails; 0 on full success

Requirements

Requirement Detail
PowerShell 5.1 or 7+ (64-bit only — LocalAccounts module unavailable in 32-bit PS on 64-bit OS)
Privileges Local administrator / SYSTEM (GPO startup script)
Modules Microsoft.PowerShell.LocalAccounts (built-in)

Key parameters

Parameter Default Description
-LogDirectory C:\Temp Directory for timestamped log files
-WhatIf — Dry-run mode
-Confirm — Prompt before each change

GPO Startup Script note

When deploying via GPO, ensure the Script Name resolves to the 64-bit PowerShell executable:

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe

Not %SystemRoot%\SysWOW64\… — the LocalAccounts module will fail silently in 32-bit mode.

Full documentation

Add-Named-Instances.md


Cleanup-Policies

Version 1.4.0 | PowerShell | Domain read access

Inventories Group Policy Objects in an Active Directory domain and reports two categories of potentially unused policies:

  • Unlinked GPOs — GPOs with no link to any OU, site, or domain container.
  • No Apply ACE — GPOs where no security principal has an Allow — Apply Group Policy ACE, meaning no one can actually apply the policy.

Output is a two-worksheet Excel workbook (or two CSV files when ImportExcel is unavailable).

How the Apply ACE check works

The script uses Get-GPPermission -All and checks for the GPPermissionType enum value GpoApply. This approach is locale-independent — earlier XML-parsing methods compared localised strings ("Apply Group Policy" / Dutch: "Groepsbeleid toepassen") which caused false positives on non-English systems.

Requirements

Requirement Detail
PowerShell 5.1 or 7+
RSAT — Group Policy GroupPolicy module — install via Add-WindowsCapability -Online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0'
RSAT — Active Directory ActiveDirectory module — install via Add-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'
ImportExcel Optional — dfinke/ImportExcel; falls back to CSV
Permissions Domain read + Group Policy Read on all GPOs

Note: Add-WindowsCapability requires Windows Update connectivity (or an internal WSUS/MEM source configured for Features on Demand). It cannot use WSUS for FOD packages on Windows 10 1809+.

Key parameters

Parameter Default Description
-Domain $env:USERDNSDOMAIN FQDN of the AD domain to query
-OutputPath Script directory Where the report is written

Report columns

Column Description
GPOName Display name
GPOId GUID in {…} notation
GpoStatus AllSettingsEnabled / Disabled / UserSettingsDisabled / ComputerSettingsDisabled
CreationTime When the GPO was created
ModificationTime When the GPO was last modified
LinkedTo Semicolon-separated list of container DNs (blank = unlinked)
IsUnlinked True when the GPO has no links
HasApplyAce False when no GpoApply ACE exists

Full documentation

Cleanup-Policies.md


Compare-GPOsByOU

Version 1.6.0 | PowerShell | Domain read access

Reports every GPO linked to each Organizational Unit and the domain root, including full WMI filter details, to enable side-by-side comparison of policies applied to the same container.

Output is a two-worksheet Excel workbook (GPOsByOU detail + Summary) or two CSV files when ImportExcel is unavailable.

What is included

  • Link properties — link order (precedence), link enabled state, link enforced (No Override) flag.
  • GPO properties — status (enabled/disabled per Computer/User half), creation and modification time, description.
  • WMI filter — display name, description, and full WQL query read directly from the domain's CN=SOM,CN=WMIPolicy,CN=System container (msWMI-Parm2 attribute).

Requirements

Requirement Detail
PowerShell 5.1 or 7+
RSAT — Group Policy GroupPolicy module — install via Add-WindowsCapability -Online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0'
RSAT — Active Directory ActiveDirectory module — install via Add-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'
ImportExcel Optional — dfinke/ImportExcel; falls back to CSV
Permissions Domain read + Group Policy Read on all GPOs + Read on CN=SOM,CN=WMIPolicy,CN=System,<DomainDN>

Key parameters

Parameter Default Description
-Domain $env:USERDNSDOMAIN FQDN of the AD domain to query
-OutputPath Script directory Where the report is written
-IncludeAll — Also include containers with no linked GPOs in the Summary sheet

Key report columns (GPOsByOU sheet)

Column Description
ContainerName / ContainerDN OU friendly name and full DN
LinkOrder GPO precedence (1 = highest)
LinkEnabled / LinkEnforced Link state flags
GPOName / GPOId Display name and GUID
GPOStatus AllSettingsEnabled / ComputerSettingsDisabled / UserSettingsDisabled / AllSettingsDisabled
WMIFilterName Attached WMI filter display name (blank = none)
WMIFilterQuery Full WQL query including namespace (root\CIMv2;SELECT …)

Full documentation

Compare-GPOsByOU.md


Generate-RDCManConfigs

Version 2.1.0 | PowerShell | AD read access

Generates Remote Desktop Connection Manager (.rdg) configuration files for one or more Active Directory domains. For each domain, all enabled Windows Server computer objects are queried and organised into nested groups that mirror the OU/canonical-path structure.

Feature Detail
Multi-domain Pass multiple FQDNs via -DomainNames
Credentials Interactive per-domain prompt, or -UseCurrentCredentials for unattended use
Overwrite protection Existing .rdg files are skipped unless -Force is specified
Dry run -WhatIf support
XPath safety OU names with embedded quotes are safely escaped via concat()

Requirements

Requirement Detail
PowerShell 5.1 or 7+
RSAT — Active Directory ActiveDirectory module
RDCMan Version 2.93+ to open generated .rdg files

Key parameters

Parameter Mandatory Description
-RDCManPath Yes Directory where .rdg files are saved (must exist)
-DomainNames Yes One or more domain FQDNs
-UseCurrentCredentials No Skip per-domain credential prompt
-Force No Overwrite existing .rdg files

Full documentation

Generate-RDCManConfigs.md


Get-AllGPOSettings

Version 1.1.0 | PowerShell | Domain read access

Reports every configured setting in every GPO in a domain, regardless of where — or whether — each GPO is linked. Unlike Compare-GPOsByOU (which reports settings per OU link), this script is scoped purely to GPOs: orphaned/unlinked GPOs are included, and each configured setting appears exactly once per GPO regardless of how many containers link it.

Output is a single-worksheet Excel workbook (or one CSV file when ImportExcel is unavailable).

Requirements

Requirement Detail
PowerShell 5.1 or 7+
RSAT — Group Policy GroupPolicy module — install via Add-WindowsCapability -Online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0'
ImportExcel Optional — dfinke/ImportExcel; falls back to CSV
Permissions Group Policy Read on all GPOs

Key parameters

Parameter Default Description
-Domain $env:USERDNSDOMAIN FQDN of the AD domain to query
-DomainController — (Windows selects) Pins all GPO queries to a specific DC
-OutputPath Script directory Where the report is written
-PassThru — Also return the collected settings to the pipeline

Settings worksheet columns

Column Description
GPOName / GPOId Display name and GUID
GPOStatus AllSettingsEnabled / UserSettingsDisabled / ComputerSettingsDisabled / AllSettingsDisabled
WMIFilterName Attached WMI filter (blank = none)
ExtensionType Administrative Templates, Security Settings, Scripts, or Windows Firewall
SettingName / SettingState / SettingValue Configured setting and its value

Full documentation

Get-AllGPOSettings.md


Get-ServiceAccounts

Version 1.8 | PowerShell | AD read + remote WMI/WinRM access

Scans all enabled Windows Server objects in Active Directory for non-standard accounts used by Windows services and scheduled tasks. Built-in accounts (LocalSystem, NT AUTHORITY\*, NT SERVICE\*) are excluded automatically.

Output per server:

  • <ServerName>_Services.csv — services with non-standard accounts
  • <ServerName>_ScheduledTasks.csv — scheduled tasks with non-standard accounts

Combined output:

  • <timestamp>_ServiceAccounts.xlsx — two-sheet workbook (Services + ScheduledTasks)
  • <timestamp>_FailedServers.txt — offline/error servers for retry (if any)

Requirements

Requirement Detail
PowerShell 7+ (uses Test-Connection -TimeoutSeconds, a PS 6.1+ parameter)
RSAT — Active Directory ActiveDirectory module
ImportExcel Required for Excel output — dfinke/ImportExcel
Network WMI/CIM access to all target servers; WinRM for scheduled task enumeration

Tip: Use the generated _FailedServers.txt as input to -ComputerList on subsequent runs to retry only offline hosts.

Key parameters

Parameter Default Description
-SearchBase Entire domain DN of the OU to search
-ComputerList — Path to a text file (one server per line) to scan instead of AD
-OutputFolder .\Output Where per-server CSV files are written
-LogFolder .\Log Where the timestamped log file is written
-PingCount 1 ICMP echo requests per host (range 1–5)

Full documentation

Get-ServiceAccounts.md


Shared (logging module)

Version 1.1.0 | PowerShell module | No direct invocation

Shared/PublicScripts.psm1 is an internal module that provides the logging, module-import, and GPO XML report parsing infrastructure shared by PowerShell scripts in this repository. Scripts import it relative to their own location — there is no need to install or publish it separately.

Function Purpose
Initialize-ScriptLog Creates the log directory, builds the timestamped filename, returns the log path
Write-ScriptLog Appends a [yyyy-MM-dd HH:mm:ss] [LEVEL] Message entry (UTF-8 NoBOM) and routes to the matching PS stream
Remove-OldLog Deletes log files matching a wildcard filter that are older than a retention threshold
Import-RequiredModule Imports one or more modules if not already loaded, logging each import via Write-ScriptLog
Get-XmlInnerText Returns the InnerText of a named child XML node, or $null when absent
Get-GpoSetting Parses a GPO XML report (Get-GPOReport) into a flat list of configured settings; safe to call from ForEach-Object -Parallel runspaces

Log filename format: yyyyMMdd_HHmmss[_Tag]_ScriptName.log

Scripts that tag logs with a domain name produce filenames such as 20260713_143022_contoso.com_Compare-GPOsByOU.log.

Full documentation

PublicScripts.md


SQL-Create-ServiceNow-User

Version 1.0 | T-SQL | SQL Server securityadmin or sysadmin

Provisions a Windows-authenticated SQL Server login and database user for the local machine account <MachineName>\servicenow, used by ServiceNow discovery and integration.

The machine name is derived dynamically from SERVERPROPERTY('MachineName') — no manual substitution required.

Accounts are created in two databases:

Database Purpose
master Server-level login + user for general connectivity
msdb User for SQL Agent / maintenance plan visibility

Prerequisites

  • The local Windows account <MachineName>\servicenow must exist before running the script.
  • Executing account requires securityadmin + db_accessadmin in master and msdb, or sysadmin.

Usage

sqlcmd -S SERVER\INSTANCE -E -i Create-ServiceNow-User.sql

Run once per SQL Server instance. Named instances have independent login stores.

Full documentation

Create-ServiceNow-User.md


Common Prerequisites

Installing RSAT (Windows 10/11, Server 2016+)

# Group Policy Management
Add-WindowsCapability -Online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0'

# Active Directory Domain Services
Add-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'

Requires Windows Update connectivity. WSUS cannot serve Features on Demand packages on Windows 10 1809 or later.

Installing ImportExcel

Install-Module -Name ImportExcel -Scope CurrentUser

Output Conventions

Pattern Meaning
YYYY-MM-dd_<name>.xlsx Date-prefixed Excel workbook
<ServerName>_Services.csv Per-server service account export
<timestamp>_FailedServers.txt Servers that could not be reached (retry input)
Log\YYYYMMDD_HHmmss_<name>.log Timestamped script log

Log entries follow the format:

[yyyy-MM-dd HH:mm:ss] [LEVEL] Message

Levels: INFO, WARN, ERROR.


Contributing

  1. Fork the repository and create a feature branch.
  2. Follow the script structure conventions in .github/copilot-instructions.md.
  3. Run Invoke-ScriptAnalyzer and resolve all warnings/errors before submitting.
  4. Keep the accompanying .md file and README.md version table in sync with any changes.
  5. Open a pull request with a clear description of what changed and why.

License

MIT