Skip to content

Instantly share code, notes, and snippets.

@davidlu1001
Created March 21, 2025 19:08
Show Gist options
  • Save davidlu1001/fa41f3eaed023a10b2b2fbcbc60b2e44 to your computer and use it in GitHub Desktop.
Save davidlu1001/fa41f3eaed023a10b2b2fbcbc60b2e44 to your computer and use it in GitHub Desktop.
Create-gMSAStartupFix.ps1
# Save this script as Create-gMSAStartupFix.ps1
param(
[Parameter(Mandatory = $true)]
[string]$ServiceName
)
# Service startup fix script content
$scriptContent = @"
# gMSA Service Startup Fix Script
# For service: $ServiceName
`$ErrorActionPreference = 'Stop'
`$logFile = "`$env:TEMP\${ServiceName}_gMSA_fix.log"
function Write-Log {
param(`$message)
`$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"`$timestamp - `$message" | Out-File -FilePath `$logFile -Append
}
Write-Log "Starting gMSA service fix script"
try {
# Wait for network and Active Directory services to be ready
Write-Log "Waiting for Active Directory services..."
Start-Sleep -Seconds 30 # Give the system some time to initialize network and other services
# Check network connectivity
`$domainController = (Get-ADDomainController -Discover).HostName
Write-Log "Found domain controller: `$domainController"
# Check current service status
`$service = Get-Service -Name "$ServiceName" -ErrorAction SilentlyContinue
if (`$null -eq `$service) {
Write-Log "Error: Service '$ServiceName' not found"
exit 1
}
Write-Log "Service status: `$(`$service.Status)"
# If service is already running, nothing to do
if (`$service.Status -eq "Running") {
Write-Log "Service is already running, no fix needed"
exit 0
}
# Get service WMI object to get logon account info
`$serviceWmi = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'"
`$accountName = `$serviceWmi.StartName
Write-Log "Service logon account: `$accountName"
# Confirm this is a gMSA account
if (-not (`$accountName -like "*`$")) {
Write-Log "Warning: Service does not appear to be using a gMSA account"
}
# Reconfigure service to refresh gMSA password cache
Write-Log "Resetting service credentials to refresh gMSA password..."
`$result = `$serviceWmi.Change(`$null, `$null, `$null, `$null, `$null, `$null, `$accountName, `$null, `$null, `$null, `$null)
if (`$result.ReturnValue -eq 0) {
Write-Log "Service credentials reset successfully"
# Try to start the service
Write-Log "Starting service..."
Start-Service -Name "$ServiceName"
# Check if service started successfully
Start-Sleep -Seconds 5
`$service = Get-Service -Name "$ServiceName"
if (`$service.Status -eq "Running") {
Write-Log "Service started successfully!"
exit 0
} else {
Write-Log "Error: Service credentials were reset but service failed to start, status: `$(`$service.Status)"
exit 1
}
} else {
Write-Log "Error: Failed to reset service credentials, error code: `$(`$result.ReturnValue)"
exit 1
}
} catch {
Write-Log "Error: `$_"
exit 1
}
"@
# Save the service fix script
$scriptPath = "$env:ProgramData\gMSAFix_$ServiceName.ps1"
$scriptContent | Out-File -FilePath $scriptPath -Encoding UTF8 -Force
Write-Host "Created service fix script: $scriptPath" -ForegroundColor Green
# Create a startup task to ensure the script runs after system startup
$taskName = "gMSAFix_$ServiceName"
$trigger = New-ScheduledTaskTrigger -AtStartup
$trigger.Delay = "PT2M" # Run after a 2-minute delay
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
# Register the task
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Principal $principal -Force
Write-Host "Created scheduled task '$taskName' to run at system startup" -ForegroundColor Green
Write-Host "The task will run with a 2-minute delay after system startup to ensure network and domain services are ready" -ForegroundColor Cyan
# Provide option to run script immediately
Write-Host "`nIf you want to run the fix immediately, execute this command:" -ForegroundColor Yellow
Write-Host "PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment