Saturday, September 27, 2008

Collecting Remote Volatile Data with PowerShell

This post is really about a script (Get-Volatile) I have been working on in PowerShell that will collect volatile data from a remote host using WMI. The aim of my script is to easily and quickly grab a bunch of useful information that may change from a host that I have an interest in for whatever reason. My script does assume thst you have permission and administrative access to the host that you are pulling information from.

Currently I use a bunch of batch files and Perl scripts written by Harlan Carvey and these are great because they help me keep an idea of what I want to achieve with my script.


The information I want to gather from a remote host with the script is the following:

  • System Time
  • Running Processes
  • Services
  • Shares
  • Sessions
  • Drivers
  • Logged on Users
  • Command History
  • Clipboard Contents
  • Hotfix/Patch Status
  • Start-up Information
  • Local Accounts & Groups
  • Networking Details & Open Ports
  • Network Connections

As my script is first run it will ask you for target and then for a name and location where you want to save the results. The results are simply a text file that can be used for further examination.

As the script is run it will have a friendly display to show where it is up to. I may well modify this to either state "1 of 2 tasks complete" or to display a progress bar.



The script is still evolving and as I have more code to add in I will update this post.

The code so far:

function Get-Volatile {

cls

$target = read-host "target?"
$Results = read-host "Results Location and Filename?"
write-host "Starting Get-Volatile V1.2 ........ Please Wait"
#
Write-Output "Current date on target as script starts" | Out-File -Width 255 $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Datenow = Get-Date
Write-Output $dateNow | Out-File -Width 255 -Append $Results
#
#OS Details
Write-Output "OS" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$OS = gwmi win32_operatingsystem -computername $target | Select CSName,Caption,CSDVersion,BuildNumber,RegisteredUser,Organization | Ft -AutoSize
Write-Output $OS | Out-File -Width 255 -Append $Results
#
write-host "Got OS........ Please Wait"
#
#
# Services & Processes
Write-Output "Running Services" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$services = gwmi win32_service -ComputerName $Target | select SystemName,ProcessID,Name,DisplayName,StartMode,State,PathName | sort StartMode | ft -AutoSize
Write-Output $Services | Out-File -Width 255 -Append $Results
#
write-host "Got Services........ Please Wait"
#
Write-Output "Running Processes" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Processes = gwmi win32_process -ComputerName $Target | select CSName,ProcessID,ProcessName,WS,CommandLine | sort WS -Descending | ft -AutoSize
Write-Output $Processes | Out-File -Width 255 -Append $Results
#
write-host "Got Processes........ Please Wait"
#
#
# Local Users and Groups
Write-Output "Local Users & Groups" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Users = gwmi Win32_UserAccount -filter "domain='$Target'" -ComputerName $Target | select name,Password*,LocalAccount,Lockout,SID | ft -AutoSize
Write-Output $Users | Out-File -Width 255 -Append $Results
#
write-host "Got Users ........ Please Wait"
#
#
$Groups = gwmi Win32_Group -filter "domain='$Target'" -ComputerName $Target | select Domain,Name,SID | ft -AutoSize
Write-Output $Groups | Out-File -Width 255 -Append $Results
#
write-host "Got Groups ........ Please Wait"
#
Write-Output "Profiles" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Profiles = Get-ChildItem -path "\\$target\C$\Documents and Settings" | Sort-Object LastWriteTime -descending | select Name,LastWriteTime | ft -AutoSize
Write-Output $Profiles | Out-File -Width 255 -Append $Results
#
#
# Networking
Write-Output "Shares" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Shares = gwmi win32_share -ComputerName $Target | ft -AutoSize
Write-Output $Shares | Out-File -Width 255 -Append $Results
#
write-host "Got Shares........ Please Wait"
#
Write-Output "Domain Details" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Domain = gwmi Win32_NTDomain -ComputerName $Target | Select DomainName,DCSiteName,DomainControllerAddress,DomainControllerName | ft -AutoSize
Write-Output $Domain | Out-File -Width 255 -Append $Results
#
write-host "Got Domain........ Please Wait"
#
# Software
#
Write-Output "Hotfixes" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Hotfixes = gwmi win32_quickfixengineering -ComputerName $Target | select CSName,HotfixID,ServicePackInEffect,Description,InstalledOn,InstalledBy | ft -AutoSize
Write-Output $Hotfixes | Out-File -Width 255 -Append $Results
#
write-host "Got Software and Hotfixes........ Please Wait"
#
Write-Output "Date and time as script finishes" | Out-File -Width 255 -Append $Results
Write-Output "" | Out-File -Width 255 -Append $Results
$Datenow = Get-Date
Write-Output "date is $dateNow" | Out-File -Width 255 -Append $Results
#
Write-Host "Finished!"
}

Get-Volatile


Any suggestions or comment are welcome as always.


Change Log.
  • 27/09/08 - First script posted - Includes Date, Services, Processes, Local Users & Groups, Shares & Hotfixes.
  • 29/09/08 - Added in command to get a list of local profiles and some section headings for the output.
  • 07/09/08 - Added codeto retreive OS details and Domain & Site Details.

7 comments:

Julie Smith said...

A script like this is exactly what I've been meaning to create!

When I run it I receive

Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESS DENIED))

Even though I have a drive mapped to the remote server with domain adminstrative credentials.

Keep up the dev!

-Julie
http://thebackroomtech.com

SynJunkie said...

Julie

Hi. Could the problem be where you are saving the results file to? I know i ran into a few permissions issues whilst testing on vista and saving directly to the root of C:

In a production environment with a XP workstation querying either a XP or W2K3 target I know the script works fine. Also I should mention that I'm using Powershell V.1

Regards

Lee

Steve said...

good job,

I receive the following message:

Get-WmiObject : Call was canceled by the message filter. (Exception from HRESULT: 0x80010002 (RPC_E_CALL_CANCELED))
At C:\scripts\Information Gathering.ps1:17 char:11
+ $OS = gwmi <<<< win32_operatingsystem -computername $target | Select CSName,Caption,CSDVersion,BuildNumber,RegisteredUser,Organization | Ft -AutoSize

SynJunkie said...

I'm not sure why you get that. What I would do is try breaking down the scipt to test on say the localhost host first and pipe the output to screen whilst testing:

Try something like:

#OS Details

gwmi win32_operatingsystem -computername localhost | Select CSName,Caption,CSDVersion,BuildNumber,RegisteredUser,Organization


then start outputting to a file to see where the issue might be.

I know it was hard as hell to get the format working so I could capture all the info without it wrapping.

let me know how you get on.

SynJunkie said...

Steve, if you email me I will send you the actual script which I have created, may be that would help.

Steve said...

what is your email address SynJunkie

SynJunkie said...

synjunkie at gmail dot com will get to me.