<# .SYNOPSIS Lists PC names and MCZ Machine IDs as CSV, ready to upload at https://mcz.software/Buy .DESCRIPTION The MCZ Machine ID is the same value "mcz license" shows on each computer: the first 80 bits of SHA-256 over "||MegaCompressorZip", in base32 (XXXX-XXXX-XXXX-XXXX). Works on Windows PowerShell 5.1 and PowerShell 7. Reading MachineGuid needs no elevation. .EXAMPLE .\Get-MczMachineId.ps1 This computer only, printed as CSV. .EXAMPLE .\Get-MczMachineId.ps1 -ComputerName (Get-Content .\pcs.txt) -OutFile .\machines.csv Remote PCs over PowerShell remoting (WinRM); unreachable PCs are reported as warnings. .EXAMPLE .\Get-MczMachineId.ps1 -OutDirectory \\server\share\mcz For a GPO startup script or Intune: each PC writes .csv to the share. Merge them with Get-ChildItem \\server\share\mcz\*.csv | Import-Csv | Export-Csv machines.csv -NoTypeInformation #> [CmdletBinding(DefaultParameterSetName = 'Local')] param( [Parameter(ParameterSetName = 'Remote', Mandatory)] [string[]] $ComputerName, [System.Management.Automation.PSCredential] $Credential, [string] $OutFile, [Parameter(ParameterSetName = 'Local')] [string] $OutDirectory ) $collect = { $b32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' $hklm = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', [Microsoft.Win32.RegistryView]::Registry64) $guid = $hklm.OpenSubKey('SOFTWARE\Microsoft\Cryptography').GetValue('MachineGuid') $drive = $env:SystemRoot.Substring(0, 2) $disk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='$drive'" $serial = [Convert]::ToUInt32($disk.VolumeSerialNumber, 16) $material = "$guid|$serial|MegaCompressorZip" $sha = [System.Security.Cryptography.SHA256]::Create() $hash = $sha.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($material)) $acc = [uint64]0; $bits = 0; $chars = New-Object System.Text.StringBuilder for ($i = 0; $i -lt 10; $i++) { $acc = (($acc -shl 8) -bor $hash[$i]) -band [uint64]65535; $bits += 8 while ($bits -ge 5) { $bits -= 5; [void]$chars.Append($b32[[int](($acc -shr $bits) -band 31)]) } } $s = $chars.ToString() [pscustomobject]@{ PcName = $env:COMPUTERNAME MachineId = '{0}-{1}-{2}-{3}' -f $s.Substring(0, 4), $s.Substring(4, 4), $s.Substring(8, 4), $s.Substring(12, 4) } } if ($PSCmdlet.ParameterSetName -eq 'Remote') { $params = @{ ComputerName = $ComputerName; ScriptBlock = $collect; ErrorAction = 'SilentlyContinue'; ErrorVariable = 'failed' } if ($Credential) { $params.Credential = $Credential } $rows = Invoke-Command @params | Select-Object PcName, MachineId foreach ($f in $failed) { Write-Warning "$($f.TargetObject): $($f.Exception.Message)" } } else { $rows = & $collect } if ($OutDirectory) { New-Item -ItemType Directory -Force -Path $OutDirectory | Out-Null $rows | Export-Csv -Path (Join-Path $OutDirectory "$env:COMPUTERNAME.csv") -NoTypeInformation -Encoding UTF8 } elseif ($OutFile) { $rows | Sort-Object PcName | Export-Csv -Path $OutFile -NoTypeInformation -Encoding UTF8 Write-Host "$(@($rows).Count) computer(s) written to $OutFile" } else { $rows | ConvertTo-Csv -NoTypeInformation }