# encoding: ascii
# api: powershell
# title: Get-CpuId
# description: Depends from PSCpu.ps1 library You can find it at https://github.com/gregzakh/PSCpu/blob/master/Lib/PSCpu.ps1
# version: 0.1
# type: function
# author: Marta Leigh
# license: CC0
# function: Get-CpuId
# x-poshcode-id: 6478
# x-archived: 2016-08-21T07:19:14
# x-published: 2016-08-18T19:07:00
#
#
function Get-CpuId {
begin {
($psdll = New-PSDllObject).set(@(
[Runtime.InteropServices.GCHandle],
[Runtime.InteropServices.Marshal]
))
$VirtualAlloc = $psdll.def(
'kernel32', 'VirtualAlloc',
'[Func[IntPtr, UIntPtr, UInt32, UInt32, IntPtr]]'
)
$VirtualFree = $psdll.def(
'kernel32', 'VirtualFree',
'[Func[IntPtr, UIntPtr, UInt32, Boolean]]'
)
[Byte[]]$bytes = switch ([IntPtr]::Size) {
4 {
0x55, #push ebp
0x8B, 0xEC, #mov ebp, esp
0x53, #push ebx
0x57, #push edi
0x8B, 0x45, 0x08, #mov eax, dword ptr[ebp+8]
0x0F, 0xA2, #cpuid
0x8B, 0x7D, 0x0C, #mov edi, dword ptr[ebp+12]
0x89, 0x07, #mov dword ptr[edi+0], eax
0x89, 0x5F, 0x04, #mov dword ptr[edi+4], ebx
0x89, 0x4F, 0x08, #mov dword ptr[edi+8], ecx
0x89, 0x57, 0x0C, #mov dword ptr[edi+12], edx
0x5F, #pop edi
0x5B, #pop ebx
0x8B, 0xE5, #mov esp, ebp
0x5D, #pop ebp
0xC3 #ret
}
8 {
0x53, #push rbx
0x49, 0x89, 0xD0, #mov r8, rdx
0x89, 0xC8, #mov eax, ecx
0x0F, 0xA2, #cpuid
0x41, 0x89, 0x40, 0x00, #mov dword ptr[r8+0], eax
0x41, 0x89, 0x58, 0x04, #mov dword ptr[r8+4], ebx
0x41, 0x89, 0x48, 0x08, #mov dword ptr[r8+8], ecx
0x41, 0x89, 0x50, 0x0C, #mov dword ptr[r8+12], edx
0x5B, #pop rbx
0xC3 #ret
}
}
$features = @{}
}
process {
try {
$ptr = $VirtualAlloc.Invoke(
[IntPtr]::Zero, (New-Object UIntPtr($bytes.Length)),
(0x1000 -bor 0x2000), 0x40
)
[Marshal]::Copy($bytes, 0, $ptr, $bytes.Length)
[Byte[]]$buf = New-Object Byte[](16)
$gch = [GCHandle]::Alloc($buf, 'Pinned')
$psdll.cpuid(0, $buf)
$gch.Free()
# cpu vendor
$vendor = "$(($str = $psdll.blocks(
$buf, $false, $true
)).ebx)$($str.edx)$($str.ecx)"
# low leaves
$ids = $psdll.blocks($buf, $true, $false).eax
$low = @()
for ($i = 0; $i -le $ids; $i++) {
$psdll.cpuid($i, $buf)
if ($i -eq 1) {
$reg = $psdll.blocks($buf, $true, $false)
$stepping = $reg.eax -band 0xF
$model = $psdll.shift('Right').Invoke($reg.eax, 4) -band 0xF
$family = $psdll.shift('Right').Invoke($reg.eax, 8) -band 0xF
$logiccpu = $psdll.shift('Right').Invoke($reg.ebx, 16) -band 0xFF
$features['fpu'] = $reg.edx -band 0x00000001
$features['vme'] = $reg.edx -band 0x00000002
$features['de'] = $reg.edx -band 0x00000004
$features['pse'] = $reg.edx -band 0x00000008
$features['tsc'] = $reg.edx -band 0x00000010
$features['msr'] = $reg.edx -band 0x00000020
$features['pae'] = $reg.edx -band 0x00000040
$features['mce'] = $reg.edx -band 0x00000080
$features['cx8'] = $reg.edx -band 0x00000100
$features['apic'] = $reg.edx -band 0x00000200
$features['sep'] = $reg.edx -band 0x00000800
$features['mtrr'] = $reg.edx -band 0x00001000
$features['pge'] = $reg.edx -band 0x00002000
$features['mca'] = $reg.edx -band 0x00004000
$features['cmov'] = $reg.edx -band 0x00008000
$features['pat'] = $reg.edx -band 0x00010000
$features['pse_36'] = $reg.edx -band 0x00020000
$features['psn'] = $reg.edx -band 0x00040000
$features['clflush'] = $reg.edx -band 0x00080000
$features['ds'] = $reg.edx -band 0x00200000
$features['acpi'] = $reg.edx -band 0x00400000
$features['mmx'] = $reg.edx -band 0x00800000
$features['fxsr'] = $reg.edx -band 0x01000000
$features['sse'] = $reg.edx -band 0x02000000
$features['sse2'] = $reg.edx -band 0x04000000
$features['ss'] = $reg.edx -band 0x08000000
$features['htt'] = $reg.edx -band 0x10000000
$features['tm'] = $reg.edx -band 0x20000000
$features['ia64'] = $reg.edx -band 0x40000000
$features['pbe'] = $reg.edx -band 0x80000000
$features['sse3'] = $reg.ecx -band 0x00000001
$features['pclmulqdq'] = $reg.ecx -band 0x00000002
$features['dtes64'] = $reg.ecx -band 0x00000004
$features['monitor'] = $reg.ecx -band 0x00000008
$features['ds_cpl'] = $reg.ecx -band 0x00000010
$features['vmx'] = $reg.ecx -band 0x00000020
$features['smx'] = $reg.ecx -band 0x00000040
$features['est'] = $reg.ecx -band 0x00000080
$features['tm2'] = $reg.ecx -band 0x00000100
$features['ssse3'] = $reg.ecx -band 0x00000200
$features['cntx_id'] = $reg.ecx -band 0x00000400
$features['sdbg'] = $reg.ecx -band 0x00000800
$features['fma'] = $reg.ecx -band 0x00001000
$features['cx16'] = $reg.ecx -band 0x00002000
$features['xtpr'] = $reg.ecx -band 0x00004000
$features['pdcm'] = $reg.ecx -band 0x00008000
$features['pcid'] = $reg.ecx -band 0x00020000
$features['dca'] = $reg.ecx -band 0x00040000
$features['sse4_1'] = $reg.ecx -band 0x00080000
$features['sse4_2'] = $reg.ecx -band 0x00100000
$features['x2apic'] = $reg.ecx -band 0x00200000
$features['movbe'] = $reg.ecx -band 0x00400000
$features['popcnt'] = $reg.ecx -band 0x00800000
$features['tsc_deadline'] = $reg.ecx -band 0x01000000
$features['aes'] = $reg.ecx -band 0x02000000
$features['xsave'] = $reg.ecx -band 0x04000000
$features['osxsave'] = $reg.ecx -band 0x08000000
$features['avx'] = $reg.ecx -band 0x10000000
$features['f16c'] = $reg.ecx -band 0x20000000
$features['rdrnd'] = $reg.ecx -band 0x40000000
$features['hypervisor'] = $reg.ecx -band 0x80000000
}
$leave = New-Object PSObject -Property $psdll.blocks($buf, $true, $false)
$leave.PSObject.TypeNames.Insert(0, 'CpuIdLeave')
$low += $leave
}
# high leaves
$psdll.cpuid(0x80000000, $buf)
$ids = $psdll.blocks($buf, $true, $false).eax
$top = @()
$name = '' # brand string
for ($i = 0x80000000; $i -le $ids; $i++) {
$psdll.cpuid($i, $buf)
if ($i -eq 0x80000001) {
$reg = $psdll.blocks($buf, $true, $false)
$features['syscall'] = $reg.edx -band 0x00000800
$features['mp'] = $reg.edx -band 0x00080000
$features['nx'] = $reg.edx -band 0x00100000
$features['mmxext'] = $reg.edx -band 0x00400000
$features['fxsr_opt'] = $reg.edx -band 0x02000000
$features['pdpe1gb'] = $reg.edx -band 0x04000000
$features['rdtscp'] = $reg.edx -band 0x08000000
$features['lm'] = $reg.edx -band 0x20000000
$features['3dnowext'] = $reg.edx -band 0x40000000
$features['3dnow'] = $reg.edx -band 0x80000000
$features['lahf_lm'] = $reg.ecx -band 0x00000001
$features['cmp_legacy'] = $reg.ecx -band 0x00000002
$features['svm'] = $reg.ecx -band 0x00000004
$features['extapic'] = $reg.ecx -band 0x00000008
$features['cr8_legacy'] = $reg.ecx -band 0x00000010
$features['abm'] = $reg.ecx -band 0x00000020
$features['sse4a'] = $reg.ecx -band 0x00000040
$features['misalingsse'] = $reg.ecx -band 0x00000080
$features['3dnowprefetch'] = $reg.ecx -band 0x00000100
$features['osvw'] = $reg.ecx -band 0x00000200
$features['ibs'] = $reg.ecx -band 0x00000400
$features['xop'] = $reg.ecx -band 0x00000800
$features['skinit'] = $reg.ecx -band 0x00001000
$features['wdt'] = $reg.ecx -band 0x00002000
$features['lwp'] = $reg.ecx -band 0x00008000
$features['fma4'] = $reg.ecx -band 0x00010000
$features['tce'] = $reg.ecx -band 0x00020000
$features['nodeid_msr'] = $reg.ecx -band 0x00080000
$features['tbm'] = $reg.ecx -band 0x00200000
$features['topoext'] = $reg.ecx -band 0x00400000
$features['perfctr_core'] = $reg.ecx -band 0x00800000
$features['perfctr_nb'] = $reg.ecx -band 0x01000000
$features['dbx'] = $reg.ecx -band 0x04000000
$features['perftsc'] = $reg.ecx -band 0x08000000
$features['pcx_l2i'] = $reg.ecx -band 0x10000000
}
if ($i -eq 0x80000002 -or $i -eq 0x80000003 -or $i -eq 0x80000004) {
$name += "$(($reg = $psdll.blocks(
$buf, $false, $true
)).eax)$($reg.ebx)$($reg.ecx)$($reg.edx)"
}
if ($i -eq 0x80000006) {
$reg = $psdll.blocks($buf, $true, $false)
$cachelsz = $reg.ecx -band 0xFF
$l2assoc = $psdll.shift('Right').Invoke($reg.ecx, 12) -band 0xF
$l2cachesz = $psdll.shift('Right').Invoke($reg.ecx, 16) -band 0xFFFF
}
$leave = New-Object PSObject -Property $psdll.blocks($buf, $true, $false)
$leave.PSObject.TypeNames.Insert(0, 'CpuIdLeave')
$top += $leave
}
$cpuid = New-Object PSObject -Property @{
Vendor = $vendor
Name = $name.Trim()
SteppingId = $stepping
Model = $model
Family = $family
LogicalCpuCount = $logiccpu
L2CacheSize = $l2cachesz
L2Associativity = $l2assoc
CacheLineSize = $cachelsz
Features = $features.Keys | ForEach-Object {
if ($features[$_]) { $_ }
} | Sort-Object
LowLeaves = $low
HighLeaves = $top
}
$cpuid.PSObject.TypeNames.Insert(0, 'CpuId')
$cpuid
}
finally {
if ($ptr) {
[void]$VirtualFree.Invoke($ptr, [UIntPtr]::Zero, 0x8000)
}
}
}
end {
$psdll.free()
}
}