System Information
TBD
Performance Counters
TBD
System Event Log
TBD
User Information
To get the path of the profile for the current user, there are many ways:
$Env:USERPROFILE
(The latter also allows to inquire for specific well known paths.)
However, this approach does not work for other users. An alternative is to use WMI:
$user = Get-WmiObject -Query "select * from win32_useraccount where Name='$UserName'"
$sid = $user.SID
$profile = Get-WmiObject -Query "select * from win32_userprofile where SID='$sid'"
$profile.LocalPath
This approach also works for discovering the profile path of remote users; you need to provide the -ComputerName
and -Credential
parameters, if necessary.However, to discover the stable locations of the other directories, you may need to do it through the registry. The values are stored in:
HKEY_USERS\<USER SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
For the documents directory, you need to read the attribute Personal
, and expand the %USERPROFILE%
with the value $profile.LocalPath
from above.
$strResult = Invoke-Command -ComputerName $ComputerName -Credential $Credential -ScriptBlock {
param($sid)
reg query "HKEY_USERS\$sid\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Personal
} -ArgumentList $user.SID
$values = $strResult[2].Split($(," ","`t"), 3, [System.StringSplitOptions]::RemoveEmptyEntries)
$values[2].Replace("%USERPROFILE%", $profile.LocalPath)
The expansion is necessary when the type of the entry is REG_EXPAND_SZ
(this is the $values[1]
); the example above works because we were lucky and the variable to expand (%USERPROFILE%
) is known.
Why couldn't we use the Get-ItemPropertyValue
command to read the registry entry in an Invoke-Command
block? The problem is that the system will first try to expand the value %USERPROFILE%
. If the user that runs the command (the user in $Credential
) differs to $user
, then the expansion will be wrong.
TODO: The PoshRegistry
module promises to do that with the command Get-RegExpandString
. It works correctly for the local system, but not for the remote system.
Software
To get a list of the installed programs:
$software = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | `
Select-Object -ExpandProperty DisplayName -ErrorAction SilentlyContinue
It is also possible to use:
$software = Get-WmiObject -Class Win32_Product | Select-Object -ExpandProperty Name
but this is much slower.