
Sorun Tespit Etme Ve Rapor Oluşturma Betiği : StoreUpdateErrorDiagnostics.TR.ps1
Kod: Tümünü seç
# ============================================================================
# Betik Adi : StoreUpdateErrorDiagnostics.TR.ps1
# Açıklama : Microsoft Store uygulama yükleme hatalarını (orn. "Windows
# Update hizmeti devre dışı bırakıldı") teşhis etmek için
# Windows Update ve Microsoft Store ile ilgili olay
# günlüklerinden son hata/uyarı kayıtlarını toplar.
# Uyumluluk : Windows PowerShell 5.1 ve PowerShell 7.x
# ============================================================================
# --- Türkçe karakter kodlamasını sabitleme bloğu ---
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
# --- PowerShell surum uyumluluk kontrolu ---
Write-Host "Tespit edilen PowerShell sürümü: $($PSVersionTable.PSVersion)" -ForegroundColor Cyan
# --- Çıktı konumu (her zaman Masaüstü, çalışma dizini kullanılmaz) ---
$desktopPath = [Environment]::GetFolderPath("Desktop")
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outputFile = Join-Path $desktopPath "StoreUpdateErrorDiagnostics_TR_$timestamp.txt"
# --- İncelenecek olay günlükleri ---
# Microsoft-Windows-Store/Operational : Microsoft Store yukleme/güncelleme olayları
# Microsoft-Windows-WindowsUpdateClient/Operational : Windows Update istemci olayları
# System : Hizmet Denetim Yöneticisi hataları (servis başlatma/durdurma sorunları)
$logsToCheck = @(
"Microsoft-Windows-Store/Operational",
"Microsoft-Windows-WindowsUpdateClient/Operational",
"System"
)
$maxEventsPerLog = 50
$lookbackHours = 72
$allResults = New-Object System.Collections.Generic.List[object]
Write-Host "`nOlay günlükleri hata ve uyarılar için taranıyor (son $lookbackHours saat)..." -ForegroundColor Yellow
foreach ($logName in $logsToCheck) {
Write-Host " - Kontrol edilen günlük: $logName" -ForegroundColor Gray
try {
$filterHash = @{
LogName = $logName
Level = 2, 3 # 2 = Hata, 3 = Uyarı
StartTime = (Get-Date).AddHours(-$lookbackHours)
}
$events = Get-WinEvent -FilterHashtable $filterHash -MaxEvents $maxEventsPerLog -ErrorAction Stop
foreach ($evt in $events) {
$allResults.Add([PSCustomObject]@{
TimeCreated = $evt.TimeCreated
LogName = $evt.LogName
Level = $evt.LevelDisplayName
ProviderName = $evt.ProviderName
Id = $evt.Id
Message = ($evt.Message -replace "`r`n", " " ).Trim()
})
}
}
catch [System.Exception] {
if ($_.Exception.Message -match "No events were found") {
Write-Host " Bu günlükte eşleşen olay bulunamadı." -ForegroundColor DarkGray
}
elseif ($_.Exception.Message -match "The specified channel could not be found") {
Write-Host " Bu günlük sistemde bulunamadı (etkinleştirilmesi gerekebilir)." -ForegroundColor DarkGray
}
else {
Write-Host " '$logName' günlüğü okunamadı: $($_.Exception.Message)" -ForegroundColor DarkYellow
}
}
}
# --- Microsoft Store'un bağlı olduğu servislerin durumunu da kontrol et ---
Write-Host "`nBağımlı servis durumları kontrol ediliyor..." -ForegroundColor Yellow
$servicesToCheck = "wuauserv", "BITS", "CryptSvc", "DcomLaunch", "RpcEptMapper", "InstallService"
$serviceResults = foreach ($svcName in $servicesToCheck) {
$svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue
if ($svc) {
[PSCustomObject]@{
ServisAdı = $svc.Name
GörünenAd = $svc.DisplayName
Durum = $svc.Status
BaşlangıçTürü = $svc.StartType
}
}
else {
[PSCustomObject]@{
ServisAdı = $svcName
GörünenAd = "Bulunamadı"
Durum = "BULUNAMADI"
BaşlangıçTürü = "Yok"
}
}
}
$serviceResults | Format-Table -AutoSize | Out-String | Write-Host
# --- Rapor içeriğini oluştur ---
$report = New-Object System.Text.StringBuilder
[void]$report.AppendLine("=================================================================")
[void]$report.AppendLine(" Store / Windows Update Hata Tanılama Raporu")
[void]$report.AppendLine(" Oluşturulma: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')")
[void]$report.AppendLine(" Geriye dönük tarama aralığı: son $lookbackHours saat")
[void]$report.AppendLine("=================================================================")
[void]$report.AppendLine("")
[void]$report.AppendLine("---- Bağımlı Servis Durumları ----")
[void]$report.AppendLine(($serviceResults | Format-Table -AutoSize | Out-String))
[void]$report.AppendLine("---- Olay Günlüğü Hata / Uyarı Kayıtları ----")
if ($allResults.Count -eq 0) {
[void]$report.AppendLine("Kontrol edilen günlüklerde eslesen hata/uyari olayi bulunamadi.")
Write-Host "`nEşleşen hata/uyarı olayı bulunamadı." -ForegroundColor Green
}
else {
$sorted = $allResults | Sort-Object TimeCreated -Descending
foreach ($item in $sorted) {
[void]$report.AppendLine("")
[void]$report.AppendLine("Zaman : $($item.TimeCreated)")
[void]$report.AppendLine("Günlük : $($item.LogName)")
[void]$report.AppendLine("Seviye : $($item.Level)")
[void]$report.AppendLine("Sağlayıcı : $($item.ProviderName)")
[void]$report.AppendLine("Olay ID : $($item.Id)")
[void]$report.AppendLine("Mesaj : $($item.Message)")
[void]$report.AppendLine("-----------------------------------------------------------")
}
Write-Host "`n$($allResults.Count) adet hata/uyarı olayı bulundu. Detaylar aşağıda ve kaydedilen raporda." -ForegroundColor Red
$sorted | Select-Object TimeCreated, LogName, Level, Id, ProviderName | Format-Table -AutoSize | Out-String | Write-Host
}
# --- Raporu Masaüstüne kaydet ---
try {
$report.ToString() | Out-File -FilePath $outputFile -Encoding UTF8 -Force
Write-Host "`nRapor şu konuma kaydedildi: $outputFile" -ForegroundColor Cyan
}
catch {
Write-Host "`nRapor Masaüstüne kaydedilemedi: $($_.Exception.Message)" -ForegroundColor Red
}
Read-Host "`nÇıkmak için ENTER tuşuna basın."
Kod: Tümünü seç
# ============================================================================
# Script Name : Update_Manager_Pro_GPO.ps1
# Description : Windows Update + Microsoft Store Policy Manager (GPO-based).
# Uses official Group Policy registry keys instead of service
# ACL hijacking wherever a real ADMX-backed policy exists.
# Also includes a full read-only service dashboard covering
# every Windows Update, Store, and Store-identity/license
# service (see companion script Update_Manager_Pro.ps1 for
# the actual start/stop/repair actions on those services).
# Compatibility: Windows PowerShell 5.1 and PowerShell 7.x (Core)
# Must be run as Administrator.
# Author history: originally generated by an earlier Claude model, hardened
# and extended following a real troubleshooting session
# (2026-09-02) that identified wlidsvc (Microsoft Account
# Sign-in Assistant) as a hidden Store-licensing dependency.
# ============================================================================
# --- Service catalog for the read-only dashboard (kept in sync with the
# companion Update_Manager_Pro.ps1 script) ---------------------------
$Script:ServiceCatalog = @(
[PSCustomObject]@{ Name = "wuauserv"; DisplayName = "Windows Update"; Category = "Core" }
[PSCustomObject]@{ Name = "BITS"; DisplayName = "Background Intelligent Transfer Service"; Category = "Core" }
[PSCustomObject]@{ Name = "DoSvc"; DisplayName = "Delivery Optimization"; Category = "Core" }
[PSCustomObject]@{ Name = "UsoSvc"; DisplayName = "Update Orchestrator Service"; Category = "Core" }
[PSCustomObject]@{ Name = "CryptSvc"; DisplayName = "Cryptographic Services"; Category = "Core" }
[PSCustomObject]@{ Name = "DcomLaunch"; DisplayName = "DCOM Server Process Launcher"; Category = "Core" }
[PSCustomObject]@{ Name = "RpcEptMapper"; DisplayName = "RPC Endpoint Mapper"; Category = "Core" }
[PSCustomObject]@{ Name = "InstallService"; DisplayName = "Microsoft Store Install Service"; Category = "Store" }
[PSCustomObject]@{ Name = "AppXSVC"; DisplayName = "AppX Deployment Service"; Category = "Store" }
[PSCustomObject]@{ Name = "ClipSVC"; DisplayName = "Client License Service"; Category = "Ident" }
[PSCustomObject]@{ Name = "WpnService"; DisplayName = "Windows Push Notification Service"; Category = "Ident" }
[PSCustomObject]@{ Name = "wlidsvc"; DisplayName = "Microsoft Account Sign-in Assistant"; Category = "Ident" }
[PSCustomObject]@{ Name = "WaaSMedicSvc"; DisplayName = "Windows Update Medic Service"; Category = "Repair"}
)
function Test-IsAdmin {
$currentUser = New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent()
)
return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Show-EngineInfo {
$engineVersion = $PSVersionTable.PSVersion.ToString()
$engineEdition = $PSVersionTable.PSEdition
Write-Host "Engine: PowerShell $engineVersion ($engineEdition)"
}
function Show-Menu {
Clear-Host
Write-Host "======================================"
Write-Host " Windows Update Policy Manager"
Write-Host " (Group Policy based)"
Write-Host "======================================"
Show-EngineInfo
if (-not (Test-IsAdmin)) {
Write-Host "WARNING: Not running as Administrator. Policy writes will fail." -ForegroundColor Yellow
}
Write-Host "--------------------------------------"
Write-Host "1. ENABLE Windows Update Auto-Download (Policy)"
Write-Host "2. DISABLE Windows Update Auto-Download (Policy)"
Write-Host "3. ENABLE Windows Update UI Access (Policy)"
Write-Host "4. DISABLE Windows Update UI Access (Policy)"
Write-Host "5. ENABLE Store Auto-Update (Policy)"
Write-Host "6. DISABLE Store Auto-Update (Policy)"
Write-Host "7. SHOW POLICY STATUS"
Write-Host "--------------------------------------"
Write-Host "8. DISABLE WaaSMedicSvc (registry Start value)"
Write-Host "9. ENABLE WaaSMedicSvc (restore to Manual)"
Write-Host "--------------------------------------"
Write-Host "10. SHOW FULL SERVICE DASHBOARD (Update + Store + Identity)"
Write-Host "11. EXPORT full dashboard + policy status to Desktop"
Write-Host "12. EXIT"
Write-Host "======================================"
}
function Ensure-RegistryPath {
param([string]$path)
if (-not (Test-Path -LiteralPath $path)) {
New-Item -Path $path -Force | Out-Null
}
}
function Invoke-GPUpdate {
Write-Host "Applying policy changes with gpupdate /force ..."
try {
$output = & gpupdate /force 2>&1
$output | ForEach-Object { Write-Host $_ }
}
catch {
Write-Host "WARNING: gpupdate /force could not be executed. Detail: $_"
Write-Host "You may need to sign out and back in, or reboot, for the policy to fully apply."
}
}
# ---- Windows Update auto-download policy (ADMX: "Configure Automatic Updates") ----
function Disable-WindowsUpdateAutoDownload {
$auPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
try {
Ensure-RegistryPath $auPath
Set-ItemProperty -Path $auPath -Name "NoAutoUpdate" -Value 1 -Type DWord -Force
Write-Host "Windows Update automatic download/install set to PERMANENT OFF." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not disable Windows Update auto-download. Detail: $_" -ForegroundColor Red
Write-Host "Make sure the script is running as Administrator."
}
}
function Enable-WindowsUpdateAutoDownload {
$auPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
try {
if (Test-Path -LiteralPath $auPath) {
Remove-ItemProperty -Path $auPath -Name "NoAutoUpdate" -ErrorAction SilentlyContinue
}
Write-Host "Windows Update automatic download/install RESTORED to default." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not restore Windows Update auto-download policy. Detail: $_" -ForegroundColor Red
}
}
# ---- Windows Update UI access policy (ADMX: "Remove access to use all Windows Update features") ----
function Disable-WindowsUpdateUIAccess {
$wuPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
try {
Ensure-RegistryPath $wuPath
Set-ItemProperty -Path $wuPath -Name "DisableWindowsUpdateAccess" -Value 1 -Type DWord -Force
Write-Host "Windows Update UI access set to PERMANENT OFF (hidden from Settings)." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not disable Windows Update UI access. Detail: $_" -ForegroundColor Red
Write-Host "Make sure the script is running as Administrator."
}
}
function Enable-WindowsUpdateUIAccess {
$wuPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
try {
if (Test-Path -LiteralPath $wuPath) {
Remove-ItemProperty -Path $wuPath -Name "DisableWindowsUpdateAccess" -ErrorAction SilentlyContinue
}
Write-Host "Windows Update UI access RESTORED to default (visible in Settings)." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not restore Windows Update UI access policy. Detail: $_" -ForegroundColor Red
}
}
# ---- Microsoft Store auto-update policy (ADMX: "Turn off Automatic Download and Install of updates") ----
function Disable-StoreAutoUpdatePolicy {
$storePath = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
try {
Ensure-RegistryPath $storePath
Set-ItemProperty -Path $storePath -Name "AutoDownload" -Value 2 -Type DWord -Force
Write-Host "Microsoft Store automatic updates set to PERMANENT OFF (policy)." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not apply Store update disable policy. Detail: $_" -ForegroundColor Red
}
}
function Enable-StoreAutoUpdatePolicy {
$storePath = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
try {
if (Test-Path -LiteralPath $storePath) {
Remove-ItemProperty -Path $storePath -Name "AutoDownload" -ErrorAction SilentlyContinue
}
Write-Host "Microsoft Store automatic updates RESTORED to default." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not restore Store update policy. Detail: $_" -ForegroundColor Red
}
}
# ---- Policy status ----
function Show-PolicyStatus {
$wuPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$auPath = "$wuPath\AU"
$storePath = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
$accessBlocked = $null
$autoOff = $null
$storeOff = $null
if (Test-Path -LiteralPath $wuPath) {
$accessBlocked = (Get-ItemProperty -Path $wuPath -Name "DisableWindowsUpdateAccess" -ErrorAction SilentlyContinue).DisableWindowsUpdateAccess
}
if (Test-Path -LiteralPath $auPath) {
$autoOff = (Get-ItemProperty -Path $auPath -Name "NoAutoUpdate" -ErrorAction SilentlyContinue).NoAutoUpdate
}
if (Test-Path -LiteralPath $storePath) {
$storeOff = (Get-ItemProperty -Path $storePath -Name "AutoDownload" -ErrorAction SilentlyContinue).AutoDownload
}
$accessLabel = "NO (default)"
if ($accessBlocked -eq 1) { $accessLabel = "YES (OFF)" }
$autoLabel = "DEFAULT / ENABLED"
if ($autoOff -eq 1) { $autoLabel = "DISABLED" }
$storeLabel = "DEFAULT / ENABLED"
if ($storeOff -eq 2) { $storeLabel = "DISABLED" }
Write-Host "Windows Update UI access blocked : $accessLabel"
Write-Host "Windows Update auto-download : $autoLabel"
Write-Host "Store auto-update policy : $storeLabel"
$svc = Get-Service -Name "WaaSMedicSvc" -ErrorAction SilentlyContinue
if ($svc) {
Write-Host "WaaSMedicSvc service status : $($svc.Status) [StartType: $($svc.StartType)]"
} else {
Write-Host "WaaSMedicSvc service status : NOT FOUND / ACCESS DENIED"
}
}
# ---- Full read-only service dashboard (diagnostic convenience) ----
function Show-FullServiceDashboard {
param([switch]$ReturnRows)
$rows = foreach ($entry in $Script:ServiceCatalog) {
$svc = Get-Service -Name $entry.Name -ErrorAction SilentlyContinue
if ($svc) {
[PSCustomObject]@{
Category = $entry.Category
ServiceName = $entry.Name
DisplayName = $entry.DisplayName
Status = $svc.Status
StartType = $svc.StartType
Flag = if ($svc.StartType -eq 'Disabled') { "DISABLED - LIKELY ROOT CAUSE" } else { "" }
}
}
else {
[PSCustomObject]@{
Category = $entry.Category
ServiceName = $entry.Name
DisplayName = $entry.DisplayName
Status = "NOT FOUND"
StartType = "N/A"
Flag = ""
}
}
}
if ($ReturnRows) { return $rows }
Write-Host "`n---- Full Service Dashboard ----" -ForegroundColor Cyan
$rows | Format-Table -AutoSize | Out-String | Write-Host
$disabledCount = ($rows | Where-Object { $_.StartType -eq 'Disabled' }).Count
if ($disabledCount -gt 0) {
Write-Host "$disabledCount service(s) are DISABLED. Use Update_Manager_Pro.ps1 (option 1 or 4) to repair them." -ForegroundColor Yellow
}
else {
Write-Host "No disabled services detected." -ForegroundColor Green
}
}
# ---- WaaSMedicSvc registry Start value (no true ADMX policy exists for this service) ----
function Disable-WaaSMedicSvc {
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$regNT = "SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$adminSid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
try {
$keyOwn = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
$regNT,
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
[System.Security.AccessControl.RegistryRights]::TakeOwnership
)
$acl = $keyOwn.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
$acl.SetOwner($adminSid)
$keyOwn.SetAccessControl($acl)
$keyOwn.Close()
$keyPerm = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
$regNT,
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
[System.Security.AccessControl.RegistryRights]::ChangePermissions
)
$acl2 = $keyPerm.GetAccessControl()
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(
$adminSid,
[System.Security.AccessControl.RegistryRights]::FullControl,
[System.Security.AccessControl.InheritanceFlags]::ContainerInherit,
[System.Security.AccessControl.PropagationFlags]::None,
[System.Security.AccessControl.AccessControlType]::Allow
)
$acl2.AddAccessRule($rule)
$keyPerm.SetAccessControl($acl2)
$keyPerm.Close()
Set-ItemProperty -Path $regPath -Name "Start" -Value 4 -ErrorAction Stop
$svc = Get-Service -Name "WaaSMedicSvc" -ErrorAction SilentlyContinue
if ($svc -and $svc.Status -eq 'Running') {
Stop-Service -Name "WaaSMedicSvc" -Force -ErrorAction SilentlyContinue
}
Write-Host "WaaSMedicSvc DISABLED (registry Start=4)." -ForegroundColor Green
Write-Host "NOTE: This is a service registry change, not an official Group Policy."
Write-Host "A major Windows Feature Update may re-enable it."
}
catch {
Write-Host "ERROR: Could not disable WaaSMedicSvc. Detail: $_" -ForegroundColor Red
Write-Host "Make sure the script is running as Administrator."
}
}
function Enable-WaaSMedicSvc {
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$regNT = "SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$adminSid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
try {
$keyPerm = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
$regNT,
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
[System.Security.AccessControl.RegistryRights]::ChangePermissions
)
$acl = $keyPerm.GetAccessControl()
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(
$adminSid,
[System.Security.AccessControl.RegistryRights]::FullControl,
[System.Security.AccessControl.InheritanceFlags]::ContainerInherit,
[System.Security.AccessControl.PropagationFlags]::None,
[System.Security.AccessControl.AccessControlType]::Allow
)
$acl.AddAccessRule($rule)
$keyPerm.SetAccessControl($acl)
$keyPerm.Close()
Set-ItemProperty -Path $regPath -Name "Start" -Value 3 -ErrorAction Stop
Write-Host "WaaSMedicSvc RESTORED to Manual (original default)." -ForegroundColor Green
}
catch {
Write-Host "ERROR: Could not restore WaaSMedicSvc. Detail: $_" -ForegroundColor Red
}
}
# ---- Export dashboard + policy status ----
function Export-FullReport {
$desktopPath = [Environment]::GetFolderPath("Desktop")
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outputFile = Join-Path $desktopPath "UpdateManagerPro_GPO_Report_$timestamp.txt"
$rows = Show-FullServiceDashboard -ReturnRows
$report = New-Object System.Text.StringBuilder
[void]$report.AppendLine("=================================================================")
[void]$report.AppendLine(" Update Manager Pro GPO - Policy + Service Dashboard Report")
[void]$report.AppendLine(" Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')")
[void]$report.AppendLine("=================================================================")
[void]$report.AppendLine("")
[void]$report.AppendLine(($rows | Format-Table -AutoSize | Out-String))
try {
$report.ToString() | Out-File -FilePath $outputFile -Encoding UTF8 -Force
Write-Host "Report saved to: $outputFile" -ForegroundColor Cyan
}
catch {
Write-Host "ERROR: Could not save report to Desktop. Detail: $_" -ForegroundColor Red
}
}
# ---- Main loop ----
if (-not (Test-IsAdmin)) {
Write-Host "WARNING: This script is not running as Administrator."
Write-Host "Policy registry keys under HKLM require elevation to write."
}
$continueLoop = $true
while ($continueLoop) {
Show-Menu
$choice = Read-Host "Your choice (1-12)"
switch ($choice) {
'1' { Enable-WindowsUpdateAutoDownload }
'2' { Disable-WindowsUpdateAutoDownload }
'3' { Enable-WindowsUpdateUIAccess }
'4' { Disable-WindowsUpdateUIAccess }
'5' { Enable-StoreAutoUpdatePolicy }
'6' { Disable-StoreAutoUpdatePolicy }
'7' { Show-PolicyStatus }
'8' { Disable-WaaSMedicSvc }
'9' { Enable-WaaSMedicSvc }
'10' { Show-FullServiceDashboard }
'11' { Export-FullReport }
'12' { $continueLoop = $false }
default { Write-Host "Invalid choice. Please try again." -ForegroundColor Yellow }
}
if ($continueLoop) {
Read-Host "`nPress ENTER to continue..."
}
}
Read-Host "`nPress ENTER to exit."
Kod: Tümünü seç
# ============================================================================
# Script Name : Update_Manager_Pro_GPO.ps1
# Description : Windows Update + Microsoft Store Policy Manager (GPO-based).
# Uses official Group Policy registry keys instead of service
# ACL hijacking wherever a real ADMX-backed policy exists.
# Also includes a full read-only service dashboard covering
# every Windows Update, Store, and Store-identity/license
# service (see companion script Update_Manager_Pro.ps1 for
# the actual start/stop/repair actions on those services).
# Compatibility: Windows PowerShell 5.1 and PowerShell 7.x (Core)
# Must be run as Administrator.
# Author history: originally generated by an earlier Claude model, hardened
# and extended following a real troubleshooting session
# (2026-09-02) that identified wlidsvc (Microsoft Account
# Sign-in Assistant) as a hidden Store-licensing dependency.
# ============================================================================
# --- Service catalog for the read-only dashboard (kept in sync with the
# companion Update_Manager_Pro.ps1 script) ---------------------------
$Script:ServiceCatalog = @(
[PSCustomObject]@{ Name = "wuauserv"; DisplayName = "Windows Update"; Category = "Core" }
[PSCustomObject]@{ Name = "BITS"; DisplayName = "Background Intelligent Transfer Service"; Category = "Core" }
[PSCustomObject]@{ Name = "DoSvc"; DisplayName = "Delivery Optimization"; Category = "Core" }
[PSCustomObject]@{ Name = "UsoSvc"; DisplayName = "Update Orchestrator Service"; Category = "Core" }
[PSCustomObject]@{ Name = "CryptSvc"; DisplayName = "Cryptographic Services"; Category = "Core" }
[PSCustomObject]@{ Name = "DcomLaunch"; DisplayName = "DCOM Server Process Launcher"; Category = "Core" }
[PSCustomObject]@{ Name = "RpcEptMapper"; DisplayName = "RPC Endpoint Mapper"; Category = "Core" }
[PSCustomObject]@{ Name = "InstallService"; DisplayName = "Microsoft Store Install Service"; Category = "Store" }
[PSCustomObject]@{ Name = "AppXSVC"; DisplayName = "AppX Deployment Service"; Category = "Store" }
[PSCustomObject]@{ Name = "ClipSVC"; DisplayName = "Client License Service"; Category = "Ident" }
[PSCustomObject]@{ Name = "WpnService"; DisplayName = "Windows Push Notification Service"; Category = "Ident" }
[PSCustomObject]@{ Name = "wlidsvc"; DisplayName = "Microsoft Account Sign-in Assistant"; Category = "Ident" }
[PSCustomObject]@{ Name = "WaaSMedicSvc"; DisplayName = "Windows Update Medic Service"; Category = "Repair"}
)
function Test-IsAdmin {
$currentUser = New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent()
)
return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Show-EngineInfo {
$engineVersion = $PSVersionTable.PSVersion.ToString()
$engineEdition = $PSVersionTable.PSEdition
Write-Host "Engine: PowerShell $engineVersion ($engineEdition)"
}
function Show-Menu {
Clear-Host
Write-Host "======================================"
Write-Host " Windows Update Policy Manager"
Write-Host " (Group Policy based)"
Write-Host "======================================"
Show-EngineInfo
if (-not (Test-IsAdmin)) {
Write-Host "WARNING: Not running as Administrator. Policy writes will fail." -ForegroundColor Yellow
}
Write-Host "--------------------------------------"
Write-Host "1. ENABLE Windows Update Auto-Download (Policy)"
Write-Host "2. DISABLE Windows Update Auto-Download (Policy)"
Write-Host "3. ENABLE Windows Update UI Access (Policy)"
Write-Host "4. DISABLE Windows Update UI Access (Policy)"
Write-Host "5. ENABLE Store Auto-Update (Policy)"
Write-Host "6. DISABLE Store Auto-Update (Policy)"
Write-Host "7. SHOW POLICY STATUS"
Write-Host "--------------------------------------"
Write-Host "8. DISABLE WaaSMedicSvc (registry Start value)"
Write-Host "9. ENABLE WaaSMedicSvc (restore to Manual)"
Write-Host "--------------------------------------"
Write-Host "10. SHOW FULL SERVICE DASHBOARD (Update + Store + Identity)"
Write-Host "11. EXPORT full dashboard + policy status to Desktop"
Write-Host "12. EXIT"
Write-Host "======================================"
}
function Ensure-RegistryPath {
param([string]$path)
if (-not (Test-Path -LiteralPath $path)) {
New-Item -Path $path -Force | Out-Null
}
}
function Invoke-GPUpdate {
Write-Host "Applying policy changes with gpupdate /force ..."
try {
$output = & gpupdate /force 2>&1
$output | ForEach-Object { Write-Host $_ }
}
catch {
Write-Host "WARNING: gpupdate /force could not be executed. Detail: $_"
Write-Host "You may need to sign out and back in, or reboot, for the policy to fully apply."
}
}
# ---- Windows Update auto-download policy (ADMX: "Configure Automatic Updates") ----
function Disable-WindowsUpdateAutoDownload {
$auPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
try {
Ensure-RegistryPath $auPath
Set-ItemProperty -Path $auPath -Name "NoAutoUpdate" -Value 1 -Type DWord -Force
Write-Host "Windows Update automatic download/install set to PERMANENT OFF." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not disable Windows Update auto-download. Detail: $_" -ForegroundColor Red
Write-Host "Make sure the script is running as Administrator."
}
}
function Enable-WindowsUpdateAutoDownload {
$auPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
try {
if (Test-Path -LiteralPath $auPath) {
Remove-ItemProperty -Path $auPath -Name "NoAutoUpdate" -ErrorAction SilentlyContinue
}
Write-Host "Windows Update automatic download/install RESTORED to default." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not restore Windows Update auto-download policy. Detail: $_" -ForegroundColor Red
}
}
# ---- Windows Update UI access policy (ADMX: "Remove access to use all Windows Update features") ----
function Disable-WindowsUpdateUIAccess {
$wuPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
try {
Ensure-RegistryPath $wuPath
Set-ItemProperty -Path $wuPath -Name "DisableWindowsUpdateAccess" -Value 1 -Type DWord -Force
Write-Host "Windows Update UI access set to PERMANENT OFF (hidden from Settings)." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not disable Windows Update UI access. Detail: $_" -ForegroundColor Red
Write-Host "Make sure the script is running as Administrator."
}
}
function Enable-WindowsUpdateUIAccess {
$wuPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
try {
if (Test-Path -LiteralPath $wuPath) {
Remove-ItemProperty -Path $wuPath -Name "DisableWindowsUpdateAccess" -ErrorAction SilentlyContinue
}
Write-Host "Windows Update UI access RESTORED to default (visible in Settings)." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not restore Windows Update UI access policy. Detail: $_" -ForegroundColor Red
}
}
# ---- Microsoft Store auto-update policy (ADMX: "Turn off Automatic Download and Install of updates") ----
function Disable-StoreAutoUpdatePolicy {
$storePath = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
try {
Ensure-RegistryPath $storePath
Set-ItemProperty -Path $storePath -Name "AutoDownload" -Value 2 -Type DWord -Force
Write-Host "Microsoft Store automatic updates set to PERMANENT OFF (policy)." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not apply Store update disable policy. Detail: $_" -ForegroundColor Red
}
}
function Enable-StoreAutoUpdatePolicy {
$storePath = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
try {
if (Test-Path -LiteralPath $storePath) {
Remove-ItemProperty -Path $storePath -Name "AutoDownload" -ErrorAction SilentlyContinue
}
Write-Host "Microsoft Store automatic updates RESTORED to default." -ForegroundColor Green
Invoke-GPUpdate
}
catch {
Write-Host "ERROR: Could not restore Store update policy. Detail: $_" -ForegroundColor Red
}
}
# ---- Policy status ----
function Show-PolicyStatus {
$wuPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$auPath = "$wuPath\AU"
$storePath = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"
$accessBlocked = $null
$autoOff = $null
$storeOff = $null
if (Test-Path -LiteralPath $wuPath) {
$accessBlocked = (Get-ItemProperty -Path $wuPath -Name "DisableWindowsUpdateAccess" -ErrorAction SilentlyContinue).DisableWindowsUpdateAccess
}
if (Test-Path -LiteralPath $auPath) {
$autoOff = (Get-ItemProperty -Path $auPath -Name "NoAutoUpdate" -ErrorAction SilentlyContinue).NoAutoUpdate
}
if (Test-Path -LiteralPath $storePath) {
$storeOff = (Get-ItemProperty -Path $storePath -Name "AutoDownload" -ErrorAction SilentlyContinue).AutoDownload
}
$accessLabel = "NO (default)"
if ($accessBlocked -eq 1) { $accessLabel = "YES (OFF)" }
$autoLabel = "DEFAULT / ENABLED"
if ($autoOff -eq 1) { $autoLabel = "DISABLED" }
$storeLabel = "DEFAULT / ENABLED"
if ($storeOff -eq 2) { $storeLabel = "DISABLED" }
Write-Host "Windows Update UI access blocked : $accessLabel"
Write-Host "Windows Update auto-download : $autoLabel"
Write-Host "Store auto-update policy : $storeLabel"
$svc = Get-Service -Name "WaaSMedicSvc" -ErrorAction SilentlyContinue
if ($svc) {
Write-Host "WaaSMedicSvc service status : $($svc.Status) [StartType: $($svc.StartType)]"
} else {
Write-Host "WaaSMedicSvc service status : NOT FOUND / ACCESS DENIED"
}
}
# ---- Full read-only service dashboard (diagnostic convenience) ----
function Show-FullServiceDashboard {
param([switch]$ReturnRows)
$rows = foreach ($entry in $Script:ServiceCatalog) {
$svc = Get-Service -Name $entry.Name -ErrorAction SilentlyContinue
if ($svc) {
[PSCustomObject]@{
Category = $entry.Category
ServiceName = $entry.Name
DisplayName = $entry.DisplayName
Status = $svc.Status
StartType = $svc.StartType
Flag = if ($svc.StartType -eq 'Disabled') { "DISABLED - LIKELY ROOT CAUSE" } else { "" }
}
}
else {
[PSCustomObject]@{
Category = $entry.Category
ServiceName = $entry.Name
DisplayName = $entry.DisplayName
Status = "NOT FOUND"
StartType = "N/A"
Flag = ""
}
}
}
if ($ReturnRows) { return $rows }
Write-Host "`n---- Full Service Dashboard ----" -ForegroundColor Cyan
$rows | Format-Table -AutoSize | Out-String | Write-Host
$disabledCount = ($rows | Where-Object { $_.StartType -eq 'Disabled' }).Count
if ($disabledCount -gt 0) {
Write-Host "$disabledCount service(s) are DISABLED. Use Update_Manager_Pro.ps1 (option 1 or 4) to repair them." -ForegroundColor Yellow
}
else {
Write-Host "No disabled services detected." -ForegroundColor Green
}
}
# ---- WaaSMedicSvc registry Start value (no true ADMX policy exists for this service) ----
function Disable-WaaSMedicSvc {
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$regNT = "SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$adminSid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
try {
$keyOwn = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
$regNT,
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
[System.Security.AccessControl.RegistryRights]::TakeOwnership
)
$acl = $keyOwn.GetAccessControl([System.Security.AccessControl.AccessControlSections]::None)
$acl.SetOwner($adminSid)
$keyOwn.SetAccessControl($acl)
$keyOwn.Close()
$keyPerm = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
$regNT,
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
[System.Security.AccessControl.RegistryRights]::ChangePermissions
)
$acl2 = $keyPerm.GetAccessControl()
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(
$adminSid,
[System.Security.AccessControl.RegistryRights]::FullControl,
[System.Security.AccessControl.InheritanceFlags]::ContainerInherit,
[System.Security.AccessControl.PropagationFlags]::None,
[System.Security.AccessControl.AccessControlType]::Allow
)
$acl2.AddAccessRule($rule)
$keyPerm.SetAccessControl($acl2)
$keyPerm.Close()
Set-ItemProperty -Path $regPath -Name "Start" -Value 4 -ErrorAction Stop
$svc = Get-Service -Name "WaaSMedicSvc" -ErrorAction SilentlyContinue
if ($svc -and $svc.Status -eq 'Running') {
Stop-Service -Name "WaaSMedicSvc" -Force -ErrorAction SilentlyContinue
}
Write-Host "WaaSMedicSvc DISABLED (registry Start=4)." -ForegroundColor Green
Write-Host "NOTE: This is a service registry change, not an official Group Policy."
Write-Host "A major Windows Feature Update may re-enable it."
}
catch {
Write-Host "ERROR: Could not disable WaaSMedicSvc. Detail: $_" -ForegroundColor Red
Write-Host "Make sure the script is running as Administrator."
}
}
function Enable-WaaSMedicSvc {
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$regNT = "SYSTEM\CurrentControlSet\Services\WaaSMedicSvc"
$adminSid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
try {
$keyPerm = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
$regNT,
[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
[System.Security.AccessControl.RegistryRights]::ChangePermissions
)
$acl = $keyPerm.GetAccessControl()
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(
$adminSid,
[System.Security.AccessControl.RegistryRights]::FullControl,
[System.Security.AccessControl.InheritanceFlags]::ContainerInherit,
[System.Security.AccessControl.PropagationFlags]::None,
[System.Security.AccessControl.AccessControlType]::Allow
)
$acl.AddAccessRule($rule)
$keyPerm.SetAccessControl($acl)
$keyPerm.Close()
Set-ItemProperty -Path $regPath -Name "Start" -Value 3 -ErrorAction Stop
Write-Host "WaaSMedicSvc RESTORED to Manual (original default)." -ForegroundColor Green
}
catch {
Write-Host "ERROR: Could not restore WaaSMedicSvc. Detail: $_" -ForegroundColor Red
}
}
# ---- Export dashboard + policy status ----
function Export-FullReport {
$desktopPath = [Environment]::GetFolderPath("Desktop")
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outputFile = Join-Path $desktopPath "UpdateManagerPro_GPO_Report_$timestamp.txt"
$rows = Show-FullServiceDashboard -ReturnRows
$report = New-Object System.Text.StringBuilder
[void]$report.AppendLine("=================================================================")
[void]$report.AppendLine(" Update Manager Pro GPO - Policy + Service Dashboard Report")
[void]$report.AppendLine(" Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')")
[void]$report.AppendLine("=================================================================")
[void]$report.AppendLine("")
[void]$report.AppendLine(($rows | Format-Table -AutoSize | Out-String))
try {
$report.ToString() | Out-File -FilePath $outputFile -Encoding UTF8 -Force
Write-Host "Report saved to: $outputFile" -ForegroundColor Cyan
}
catch {
Write-Host "ERROR: Could not save report to Desktop. Detail: $_" -ForegroundColor Red
}
}
# ---- Main loop ----
if (-not (Test-IsAdmin)) {
Write-Host "WARNING: This script is not running as Administrator."
Write-Host "Policy registry keys under HKLM require elevation to write."
}
$continueLoop = $true
while ($continueLoop) {
Show-Menu
$choice = Read-Host "Your choice (1-12)"
switch ($choice) {
'1' { Enable-WindowsUpdateAutoDownload }
'2' { Disable-WindowsUpdateAutoDownload }
'3' { Enable-WindowsUpdateUIAccess }
'4' { Disable-WindowsUpdateUIAccess }
'5' { Enable-StoreAutoUpdatePolicy }
'6' { Disable-StoreAutoUpdatePolicy }
'7' { Show-PolicyStatus }
'8' { Disable-WaaSMedicSvc }
'9' { Enable-WaaSMedicSvc }
'10' { Show-FullServiceDashboard }
'11' { Export-FullReport }
'12' { $continueLoop = $false }
default { Write-Host "Invalid choice. Please try again." -ForegroundColor Yellow }
}
if ($continueLoop) {
Read-Host "`nPress ENTER to continue..."
}
}
Read-Host "`nPress ENTER to exit."
Kod: Tümünü seç
=================================================================
Update Manager Pro GPO - Policy + Service Dashboard Report
Generated: 2026-09-02 07:55:54
=================================================================
Category ServiceName DisplayName Status StartType Flag
-------- ----------- ----------- ------ --------- ----
Core wuauserv Windows Update Stopped Manual
Core BITS Background Intelligent Transfer Service Stopped Manual
Core DoSvc Delivery Optimization Stopped Manual
Core UsoSvc Update Orchestrator Service Stopped Automatic
Core CryptSvc Cryptographic Services Running Automatic
Core DcomLaunch DCOM Server Process Launcher Running Automatic
Core RpcEptMapper RPC Endpoint Mapper Running Automatic
Store InstallService Microsoft Store Install Service Stopped Manual
Store AppXSVC AppX Deployment Service Stopped Manual
Ident ClipSVC Client License Service Stopped Automatic
Ident WpnService Windows Push Notification Service Running Automatic
Ident wlidsvc Microsoft Account Sign-in Assistant Stopped Manual
Repair WaaSMedicSvc Windows Update Medic Service Stopped Disabled DISABLED - LIKELY ROOT CAUSE

