Guide Cek License Windows Server – Windows Server License Inventory 1. Tujuan Script ini digunakan untuk melakukan pengecekan license yang terdeteksi pada Windows Server, meliputi: Windows Server License Windows Server Edition Windows Activation Status License Type License Channel KMS Configuration SQL Server SQL Server Edition & Version Remote Desktop Services (RDS) RDS Licensing Mode RDS CAL CPU / Core Export hasil pengecekan ke CSV 2. Persiapan Pastikan: Server menggunakan Windows Server. User memiliki akses Administrator . Gunakan Windows PowerShell ISE . Tidak perlu mengubah Execution Policy secara permanen karena script sudah menjalankan: Set-ExecutionPolicy-ScopeProcess-ExecutionPolicyBypass-Force 3. Menjalankan Script Step 1 – Buka PowerShell ISE Klik: Start → Windows PowerShell → Windows PowerShell ISE Kemudian pilih: Run as Administrator Step 2 – Buat New Script Pada PowerShell ISE pilih: File → New atau tekan: Ctrl + N Step 3 – Copy Script Copy seluruh script Windows Server License Inventory yang diberikan sebelumnya. Paste ke bagian Script Pane PowerShell ISE. Tidak perlu membuat file .ps1 terlebih dahulu. Step 4 – Jalankan Script Tekan: F5 atau pilih: Debug → Run/Continue Script akan melakukan pengecekan secara otomatis. # ============================================================ # WINDOWS SERVER LICENSE INVENTORY # Copy-Paste directly into PowerShell ISE # Run PowerShell ISE as Administrator # ============================================================ # Allow script execution for current PowerShell session only Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force $ErrorActionPreference = "SilentlyContinue" $ComputerName = $env:COMPUTERNAME $TimeStamp = Get-Date -Format "yyyyMMdd_HHmmss" $OutputPath = Join-Path $env:USERPROFILE "Desktop\License_Inventory_${ComputerName}_${TimeStamp}.csv" $Inventory = @() # ============================================================ # FUNCTIONS # ============================================================ function Write-Section { param([string]$Title) Write-Host "" Write-Host "============================================================" -ForegroundColor Cyan Write-Host $Title -ForegroundColor Cyan Write-Host "============================================================" -ForegroundColor Cyan } function Write-Field { param( [string]$Name, [string]$Value, [ConsoleColor]$Color = [ConsoleColor]::White ) Write-Host ("{0,-22}: {1}" -f $Name, $Value) -ForegroundColor $Color } function Add-Inventory { param( [string]$Product, [string]$Edition, [string]$LicenseType, [string]$Status, [string]$Details ) $script:Inventory += [PSCustomObject]@{ ComputerName = $ComputerName Product = $Product Edition = $Edition LicenseType = $LicenseType Status = $Status Details = $Details } } # ============================================================ # HEADER # ============================================================ Clear-Host Write-Host "" Write-Host "============================================================" -ForegroundColor Green Write-Host " WINDOWS SERVER LICENSE INVENTORY" -ForegroundColor Green Write-Host "============================================================" -ForegroundColor Green Write-Host "" Write-Field "Computer Name" $ComputerName Write-Field "Report Date" (Get-Date -Format "yyyy-MM-dd HH:mm:ss") # ============================================================ # 1. WINDOWS SERVER LICENSE # ============================================================ Write-Section "1. WINDOWS SERVER LICENSE" $OS = Get-CimInstance Win32_OperatingSystem $WindowsLicense = Get-CimInstance SoftwareLicensingProduct | Where-Object { $_.Name -like "Windows*" -and $_.PartialProductKey } | Sort-Object LicenseStatus -Descending | Select-Object -First 1 $LicenseStatus = "Unknown" $LicenseType = "Unknown" $LicenseChannel = "Unknown" $PartialKey = "-" $Description = "-" $LicenseName = "-" $Expiration = "-" if ($WindowsLicense) { switch ($WindowsLicense.LicenseStatus) { 0 { $LicenseStatus = "Unlicensed" } 1 { $LicenseStatus = "Licensed" } 2 { $LicenseStatus = "OOB Grace" } 3 { $LicenseStatus = "OOT Grace" } 4 { $LicenseStatus = "Non-Genuine Grace" } 5 { $LicenseStatus = "Notification" } 6 { $LicenseStatus = "Extended Grace" } default { $LicenseStatus = "Unknown" } } $LicenseName = $WindowsLicense.Name $Description = $WindowsLicense.Description $PartialKey = $WindowsLicense.PartialProductKey # -------------------------------------------------------- # Detect License Type / Channel # -------------------------------------------------------- if ( $Description -match "TIMEBASED_EVAL" -or $Description -match "EVAL" -or $LicenseName -match "Eval" ) { $LicenseType = "EVALUATION" $LicenseChannel = "TIMEBASED_EVAL" } elseif ($Description -match "KMS") { $LicenseType = "VOLUME" $LicenseChannel = "KMS" } elseif ($Description -match "MAK") { $LicenseType = "VOLUME" $LicenseChannel = "MAK" } elseif ($Description -match "Retail") { $LicenseType = "RETAIL" $LicenseChannel = "RETAIL" } elseif ($Description -match "OEM") { $LicenseType = "OEM" $LicenseChannel = "OEM" } elseif ($Description -match "Volume") { $LicenseType = "VOLUME" $LicenseChannel = "VOLUME" } # -------------------------------------------------------- # Expiration # -------------------------------------------------------- $XPR = cscript.exe //nologo ` "$env:SystemRoot\System32\slmgr.vbs" /xpr 2>&1 if ($XPR) { $Expiration = ($XPR | Out-String).Trim() } } Write-Field "OS" $OS.Caption Write-Field "Version" $OS.Version Write-Field "Build" $OS.BuildNumber Write-Field "Architecture" $OS.OSArchitecture Write-Host "" Write-Field "License Status" $LicenseStatus if ($LicenseType -eq "EVALUATION") { Write-Field "License Type" $LicenseType Yellow Write-Field "License Channel" $LicenseChannel Yellow } else { Write-Field "License Type" $LicenseType Write-Field "License Channel" $LicenseChannel } Write-Field "License Name" $LicenseName Write-Field "Description" $Description Write-Field "Partial Product Key" $PartialKey Write-Field "Expiration" $Expiration Write-Host "" if ($LicenseType -eq "EVALUATION") { Write-Host "ASSESSMENT : EVALUATION LICENSE" -ForegroundColor Yellow } elseif ($LicenseStatus -eq "Licensed") { Write-Host "ASSESSMENT : LICENSE ACTIVATED" -ForegroundColor Green } else { Write-Host "ASSESSMENT : CHECK LICENSE STATUS" -ForegroundColor Red } Add-Inventory ` "Windows Server" ` $OS.Caption ` $LicenseType ` $LicenseStatus ` "Channel=$LicenseChannel; PartialKey=$PartialKey; Expiration=$Expiration" # ============================================================ # 2. KMS # ============================================================ Write-Section "2. WINDOWS ACTIVATION / KMS" $KMSPath = ` "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform" $KMSConfig = Get-ItemProperty $KMSPath $KMSServer = $KMSConfig.KeyManagementServiceName $KMSPort = $KMSConfig.KeyManagementServicePort if ($KMSServer) { Write-Field "KMS Server" $KMSServer Write-Field "KMS Port" $KMSPort Write-Field "KMS Status" "Configured" Green } else { Write-Field "KMS Server" "Not configured" Write-Field "KMS Status" "Not configured" } # ============================================================ # 3. SQL SERVER # ============================================================ Write-Section "3. SQL SERVER" $SQLServices = Get-Service | Where-Object { $_.Name -eq "MSSQLSERVER" -or $_.Name -like "MSSQL$*" } if (-not $SQLServices) { Write-Field "SQL Server" "NOT DETECTED" Yellow Write-Field "Status" "SQL Server instance not found" Add-Inventory ` "SQL Server" ` "-" ` "-" ` "Not Installed / Not Detected" ` "-" } else { foreach ($Service in $SQLServices) { if ($Service.Name -eq "MSSQLSERVER") { $InstanceName = "MSSQLSERVER" $ConnectionName = "localhost" } else { $InstanceName = $Service.Name -replace "^MSSQL\$", "" $ConnectionName = "localhost\$InstanceName" } Write-Host "" Write-Field "Instance" $InstanceName Write-Field "Service Status" $Service.Status $SQLFound = $false if (Get-Command sqlcmd.exe -ErrorAction SilentlyContinue) { $SQLQuery = @" SELECT CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(128)), CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(128)), CAST(SERVERPROPERTY('Edition') AS NVARCHAR(128)), CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)), CAST(SERVERPROPERTY('ProductLevel') AS NVARCHAR(128)); "@ $SQLResult = sqlcmd.exe ` -S $ConnectionName ` -E ` -Q $SQLQuery ` -W ` -s "|" 2>$null if ($SQLResult) { $Line = $SQLResult | Where-Object { $_ -and $_ -notmatch "^-+" -and $_ -notmatch "ServerName" } | Select-Object -First 1 if ($Line) { $Fields = $Line -split "\|" if ($Fields.Count -ge 5) { $SQLEdition = $Fields[2].Trim() $SQLVersion = $Fields[3].Trim() $SQLLevel = $Fields[4].Trim() $SQLFound = $true Write-Field "Edition" $SQLEdition Write-Field "Version" $SQLVersion Write-Field "Product Level" $SQLLevel Add-Inventory ` "SQL Server" ` $SQLEdition ` "See Agreement" ` "Detected" ` "Instance=$InstanceName; Version=$SQLVersion; ProductLevel=$SQLLevel" } } } } if (-not $SQLFound) { Write-Field "SQL Details" ` "SQL detected but detailed query unavailable" ` Yellow Add-Inventory ` "SQL Server" ` "Detected" ` "Unknown" ` "Service Detected" ` "Instance=$InstanceName" } } } # ============================================================ # 4. RDS # ============================================================ Write-Section "4. REMOTE DESKTOP SERVICES (RDS)" $RDSFeatures = Get-WindowsFeature | Where-Object { $_.Name -like "RDS*" -and $_.Installed } $RDSService = Get-Service TermServLicensing if (-not $RDSFeatures) { Write-Field "RDS Role" "NOT INSTALLED" Yellow Write-Field "RDS Licensing" "N/A" Add-Inventory ` "RDS" ` "-" ` "-" ` "Not Installed" ` "-" } else { Write-Field "RDS Role" "INSTALLED" Green foreach ($Feature in $RDSFeatures) { Write-Field "Role / Feature" $Feature.DisplayName } # -------------------------------------------------------- # RDS Licensing Service # -------------------------------------------------------- if ($RDSService) { Write-Field "Licensing Service" $RDSService.Status } else { Write-Field "Licensing Service" "Not Installed" } # -------------------------------------------------------- # RDS Licensing Mode # -------------------------------------------------------- $RDSLicensingPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM\Licensing Core" $RDSConfig = Get-ItemProperty $RDSLicensingPath if ($RDSConfig -and $RDSConfig.LicensingMode) { switch ($RDSConfig.LicensingMode) { 2 { $RDSMode = "Per Device" } 4 { $RDSMode = "Per User" } default { $RDSMode = "Unknown ($($RDSConfig.LicensingMode))" } } Write-Field "Licensing Mode" $RDSMode } else { $RDSMode = "Not Configured" Write-Field "Licensing Mode" $RDSMode Yellow } # -------------------------------------------------------- # RDS License Server # -------------------------------------------------------- $LicenseServerFound = $false $PolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" if (Test-Path $PolicyPath) { $Policy = Get-ItemProperty $PolicyPath if ($Policy.licenseServers) { Write-Field "License Server" $Policy.licenseServers $LicenseServerFound = $true } } if (-not $LicenseServerFound) { Write-Field "License Server" "Not explicitly configured" } # -------------------------------------------------------- # RDS CAL # -------------------------------------------------------- try { $CALPacks = Get-CimInstance ` -Namespace "Root/CIMV2/TerminalServices" ` -ClassName Win32_TSLicenseKeyPack if ($CALPacks) { Write-Host "" Write-Host "RDS CAL INVENTORY" -ForegroundColor Cyan Write-Host "------------------------------------------------------------" foreach ($CAL in $CALPacks) { Write-Field "Product Version" $CAL.ProductVersion Write-Field "Product Type" $CAL.ProductType Write-Field "License Type" $CAL.LicenseType Write-Field "Total CAL" $CAL.TotalLicenses Write-Field "Issued CAL" $CAL.IssuedLicenses Write-Field "Available CAL" $CAL.AvailableLicenses Write-Field "Expiration" $CAL.ExpirationDate Add-Inventory ` "RDS CAL" ` $CAL.ProductVersion ` $CAL.LicenseType ` "Installed" ` "Total=$($CAL.TotalLicenses); Issued=$($CAL.IssuedLicenses); Available=$($CAL.AvailableLicenses)" } } else { Write-Field "RDS CAL" "NO CAL PACK DETECTED" Yellow Add-Inventory ` "RDS CAL" ` "-" ` "-" ` "No CAL Pack Detected" ` "-" } } catch { Write-Field "RDS CAL" "Unable to query" Yellow } } # ============================================================ # 5. HARDWARE / CPU # ============================================================ Write-Section "5. HARDWARE / CPU" $CPU = Get-CimInstance Win32_Processor $Socket = ($CPU | Measure-Object).Count $PhysicalCore = ( $CPU | Measure-Object -Property NumberOfCores -Sum ).Sum $LogicalCPU = ( $CPU | Measure-Object -Property NumberOfLogicalProcessors -Sum ).Sum $CPUModel = ( $CPU | Select-Object -ExpandProperty Name -Unique ) -join "; " Write-Field "CPU" $CPUModel Write-Field "Socket" $Socket Write-Field "Physical Core" $PhysicalCore Write-Field "Logical CPU" $LogicalCPU # ============================================================ # 6. LICENSE SUMMARY # ============================================================ Write-Section "LICENSE SUMMARY" Write-Host "" $Inventory | Select-Object Product, Edition, LicenseType, Status | Format-Table -AutoSize # ============================================================ # 7. EXPORT CSV # ============================================================ $Inventory | Export-Csv ` -Path $OutputPath ` -NoTypeInformation ` -Encoding UTF8 Write-Host "" Write-Host "============================================================" -ForegroundColor Green Write-Host "AUDIT COMPLETED" -ForegroundColor Green Write-Host "============================================================" -ForegroundColor Green Write-Host "" Write-Host "CSV Report:" -ForegroundColor Cyan Write-Host $OutputPath -ForegroundColor White Write-Host "" Write-Host "The CSV report has been saved to the Desktop." -ForegroundColor Green Write-Host "" 4. Hasil Pengecekan Script akan menampilkan beberapa bagian. 4.1 Windows Server License Contoh: ============================================================ 1. WINDOWS SERVER LICENSE ============================================================ OS : Microsoft Windows Server 2022 Standard Evaluation Version : 10.0.20348 Build : 20348 Architecture : 64-bit License Status : Licensed License Type : EVALUATION License Channel : TIMEBASED_EVAL License Name : Windows(R), ServerStandardEval edition Description : Windows(R) Operating System, TIMEBASED_EVAL channel Partial Product Key : XXXXX Expiration : ... Parameter yang perlu diperhatikan Parameter Keterangan OS Windows Server Edition Version Versi Windows Build Build Windows License Status Status aktivasi License Type Jenis license yang terdeteksi License Channel Channel aktivasi/license Partial Product Key 5 digit terakhir product key Expiration Informasi masa berlaku Contoh Evaluation Jika hasil menunjukkan: License Status : Licensed License Type : EVALUATION License Channel : TIMEBASED_EVAL maka server tersebut menggunakan Evaluation License , walaupun License Status menunjukkan Licensed . 5. Windows Activation / KMS Script kemudian mengecek konfigurasi KMS. Contoh: ============================================================ 2. WINDOWS ACTIVATION / KMS ============================================================ KMS Server : kms.company.local KMS Port : 1688 KMS Status : Configured Jika tidak menggunakan KMS: KMS Server : Not configured KMS Status : Not configured Informasi ini membantu mengetahui apakah Windows menggunakan KMS activation . 6. SQL Server Script akan mengecek apakah terdapat SQL Server pada server. Jika tidak ditemukan: ============================================================ 3. SQL SERVER ============================================================ SQL Server : NOT DETECTED Status : SQL Server instance not found Jika ditemukan: Instance : MSSQLSERVER Service Status : Running Edition : Enterprise Edition Version : 16.0.x Product Level : CUxx Informasi ini digunakan untuk inventory: SQL Server Instance SQL Server Edition SQL Server Version Product Level Service Status Catatan: SQL Server Edition yang terdeteksi dari server tidak secara otomatis membuktikan bahwa license entitlement perusahaan sudah sesuai. Untuk compliance tetap perlu dibandingkan dengan Microsoft licensing agreement/entitlement. 7. Remote Desktop Services Script juga mengecek RDS. Jika RDS tidak terinstall: ============================================================ 4. REMOTE DESKTOP SERVICES (RDS) ============================================================ RDS Role : NOT INSTALLED RDS Licensing : N/A Jika RDS terinstall: RDS Role : INSTALLED Role / Feature : Remote Desktop Session Host Licensing Service : Running Licensing Mode : Per User License Server : RDS-LICENSE01 8. RDS CAL Jika server merupakan RDS License Server dan CAL dapat dideteksi, hasilnya akan ditampilkan seperti: RDS CAL INVENTORY ------------------------------------------------------------ Product Version : Windows Server 2022 Product Type : RDS CAL License Type : Per User Total CAL : 50 Issued CAL : 32 Available CAL : 18 Expiration : ... Informasi utama: Parameter Keterangan Product Version Versi RDS CAL Product Type Jenis CAL License Type Per User / Per Device Total CAL Total CAL yang terinstall Issued CAL CAL yang sudah digunakan Available CAL CAL yang masih tersedia Expiration Masa berlaku jika tersedia 9. Hardware / CPU Script juga mengambil informasi CPU. Contoh: ============================================================ 5. HARDWARE / CPU ============================================================ CPU : Intel(R) Xeon(R) Gold 6338N CPU @ 2.20GHz Socket : 2 Physical Core : 16 Logical CPU : 16 Informasi ini berguna terutama untuk inventory dan assessment SQL Server Per Core licensing . 10. License Summary Bagian ini merupakan quick overview dari license yang ditemukan. Contoh: ============================================================ LICENSE SUMMARY ============================================================ Product Edition LicenseType Status ------- ------- ----------- ---------------- Windows Server 2022 Standard Evaluation EVALUATION Licensed SQL Server - - Not Installed RDS - - Not Installed RDS CAL - - No CAL Pack Bagian ini dapat digunakan untuk melihat secara cepat: Apa saja software/license yang terdeteksi. Edition yang digunakan. Jenis license. Status license. 11. CSV Report Setelah proses selesai, script akan otomatis membuat file CSV di Desktop . Contoh: C:\Users\\Desktop\ License_Inventory_SERVER01_20260923_124500.csv Nama file menggunakan format: License_Inventory__.csv Contoh: License_Inventory_SSULIS-WINDOWS_20260923_124500.csv File tersebut dapat dibuka menggunakan Microsoft Excel. 12. Informasi yang Dicatat untuk Inventory Untuk kebutuhan license inventory, informasi utama yang perlu diperhatikan adalah: Windows Server Computer Name OS / Edition Version Build License Status License Type License Channel Expiration KMS Server SQL Server Instance Service Status Edition Version Product Level CPU / Physical Core RDS RDS Role Licensing Service Licensing Mode License Server RDS CAL Total CAL Issued CAL Available CAL 13. Contoh Interpretasi Misalnya hasil server: Windows Server Edition : Windows Server 2022 Standard Evaluation Status : Licensed License Type : EVALUATION Channel : TIMEBASED_EVAL Maka pada inventory dapat dicatat: Item Result Windows Edition Windows Server 2022 Standard License Type Evaluation License Channel TIMEBASED_EVAL Activation Status Licensed Review Evaluation license Jadi jangan hanya melihat License Status = Licensed . License Type dan License Channel juga harus diperiksa. 14. Troubleshooting Script tidak berjalan Pastikan PowerShell ISE dijalankan sebagai: Administrator Kemudian tekan: F5 SQL Server terdeteksi tetapi detail tidak muncul Script menggunakan sqlcmd.exe untuk mengambil detail SQL Server. Cek apakah tersedia: Get-Commandsqlcmd.exe Jika tidak ditemukan, hasil SQL Server mungkin hanya menunjukkan bahwa service SQL Server terdeteksi. RDS CAL tidak muncul Jika: RDS CAL : NO CAL PACK DETECTED bukan berarti perusahaan pasti tidak mempunyai RDS CAL. Artinya CAL pack tidak dapat dideteksi pada server yang sedang diperiksa . RDS CAL dapat saja berada pada RDS License Server yang berbeda . 15. Output yang Digunakan untuk Audit Untuk setiap server, simpan: 1. Screenshot / output License Summary 2. CSV License Inventory Kemudian inventory dapat dikumpulkan menjadi satu database/Excel dengan struktur: Server ↓ Windows License ↓ SQL Server ↓ RDS ↓ RDS CAL ↓ CPU/Core Catatan: hasil script merupakan technical license discovery . Untuk menentukan compliance secara final, hasil tersebut tetap perlu dibandingkan dengan license entitlement atau Microsoft agreement yang dimiliki perusahaan.