One thing I wish I had was more time to re-visit my old scripts and re-write them as I often look at my old script and it sends a cold shiver down my spine as I now know a better way of doing things.
As I was away for the weekend and had no internet connection I took my old Audit Script with me, I had a few personal objectives that I wanted to achieve by re-writing this code and I was also asked by a friend who has started to adapt the code into other formats.
So, this is version 3 of the script, you can see how much I have learnt recently as V1 of this script was over 1000 lines, V2 of this script was 847 and now with the new improved code it is a miniscule 459 lines
My main objectives for this version of the script were:
- Apply my newly learnt PS Skills to optimise the code
- Use a HTML format that worked in all browsers
- Make the code easy to follow
- Make the code easy for other people to produce similar reports of other systems
When you see the code and use the output I hope you will agree I have achieved each of these. The code now works with all browsers I have tested and is very easily customisable.
Check out a screenshot of the output below:
As before this script can be run in two modes, if you run it as it is you will produce an audit of your current machine or if you run it with a path to a text file it will read a list of server names and audit each machine saving a separate html file for each one.
Download
Downloaded 6303 times
<SMALL RANT> Someone took my last script and removed my name from the code and then posted it as their own code on a powershell site, whilst I do not mind people adjusting and re-using my code, in fact there is nothing better than seeing how other people use my code I would prefer that you at least make a reference to my site or me in your comments.
I have been under certain pressure to start charging for some of my code which I have resisted as I like contributing and making the life of my fellow admins easier, claiming my code as your own is just plain rude.</SMALL RANT>
I added the following to get local user and group enumeration. Thanks for the great script!
Write-Output “..Users”
$Users = Get-WmiObject -ComputerName $Target Win32_UserAccount -filter “LocalAccount=True” | Select-Object Name,Disabled
$MyReport += Get-CustomHeader “1″ “Users”
$MyReport += Get-HTMLTable ($Users)
$MyReport += Get-CustomHeaderClose
Write-Output “..Groups”
$Groups = Get-WmiObject -ComputerName $Target Win32_Group -filter “LocalAccount=True” | Select-Object Name
$MyReport += Get-CustomHeader “1″ “Groups”
$MyReport += Get-HTMLTable ($Groups)
$MyReport += Get-CustomHeaderClose
After spending 2 hours looks for a better inventory script then I could write…. (bang head on desk) I should have have figured Alan had something like this… After all he is a legend
Script is really greate could you help me in how can i convert this into csv format appreciate your support.
Hi All
Please help me…im getting this error msg
PS C:\Users\Administrator\Desktop> C:\Users\Administrator\Desktop\audit.ps1
No list specified, using SGGSINTSYSVW212
Collating Detail for SGGSINTSYSVW212
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:165 char:33
+ $ComputerSystem = Get-WmiObject <<<< -computername $Target Win32_ComputerSystem
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:176 char:35
+ $OperatingSystems = Get-WmiObject <<<< -computername $Target Win32_OperatingSystem
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:177 char:27
+ $TimeZone = Get-WmiObject <<<< -computername $Target Win32_Timezone
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:178 char:28
+ $Keyboards = Get-WmiObject <<<< -computername $Target Win32_Keyboard
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:179 char:29
+ $SchedTasks = Get-WmiObject <<<< -computername $Target Win32_ScheduledJob
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:181 char:34
+ $RecoveryOptions = Get-WmiObject <<<< -computername $Target Win32_OSRecoveryConfiguration
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
You cannot call a method on a null-valued expression.
At C:\Users\Administrator\Desktop\audit.ps1:190 char:45
+ $LBTime=$OperatingSystems.ConvertToDateTime <<<< ($OperatingSystems.Lastbootuptime)
+ CategoryInfo : InvalidOperation: (ConvertToDateTime:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
..Regional Options
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:192 char:31
+ $ObjKeyboards = Get-WmiObject <<<< -ComputerName $Target Win32_Keyboard
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
..Hotfix Information
Get-WmiObject :
At C:\Users\Administrator\Desktop\audit.ps1:280 char:33
+ $colQuickFixes = Get-WmiObject <<<< Win32_QuickFixEngineering
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Thanks Alan for the quick reply. That did the trick
Hi Alan,
Love the script. One problem I am running into is when I execute the script against a list of servers, I only get patching information for the current machine that I am executing the script on. I get all of the outputs the way it is supposed to be, except the wrong patching information. I am using WIN7 enterprise and executing the script agains Win2k3 servers.
I do have admin access to the remote servers. Please help. To execute, I put the script as well as the list of servers (auditlist.txt) in the same directory. I am using the following to execute .\Audit.ps1 auditlist.txt. Please help.
Ahh, well found – there is a mistake in the script, there is a line which reads:
$colQuickFixes = Get-WmiObject Win32_QuickFixEngineering
change it to
$colQuickFixes = Get-WmiObject -ComputerName $Target Win32_QuickFixEngineering
Thanks for the great scripts. For some odd reason having this data up to date and internally public keeps my auditors off my back.
Great script! any chance you could update it to include the following
1) Obtain page swap file size in MB
2) Check for software installed eg sysmantec, Altiris
3) Diplay WINS settings “Enable LMHOSTS Lookup” and “Enable NetBIOS over TCP/IP
4) Data Execution Prevention settings
5) System variables
6) Remote desktop settings
Al, Thanks for this script I learnt about through a class
with T Lee. It has taught me so much
Al, Thanks for this script I learnt about through a class
with T Lee. It has taught so much
Pingback: Free monitoring and inventory software like ms system center configuration manager?
Great script!
I was running into a bit of an issue with Win32_Product class, getting following error message:
Get-WmiObject : Generic failure
At C:\temp\AuditScript\Audit.ps1:330 char:46
+ $MyReport += Get-HTMLTable (get-wmiobject <<<< Win32_Product | select Name,Version,Vendor,InstallDate)
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
I had to change"get-wmiobject" to "Get-wmiobject" and it worked fine. I'm not sure why there was a case sensitivity issue, since running "get-wmiobject Win32_Product" directly worked fine.
Anyhow, great work!
@Rob P.
Will do Rob, although you could add it yourslef, honestly the code is very easy to change !
Hi Alan,
Could you possibly add in the OS Build number in you next release ?
Have a great Christmas. Rob…
@Lucas
Nice one, love it
Great script!
A couple of changes I made when I used it in my environment:
1. Started with a ping check (using Win32_PingStatus) to make sure that the target computers are online
2. Added the following code to get software inventory on Windows 2003 servers where the Win32_Product had not been installed (code goes in the Else portion of the Win32_Product check):
$colApps = @()
$hklm = 2147483650
$key = “SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”
$wmi = [wmiclass]“\\$Target\root\default:stdRegProv”
$subkeys = $wmi.EnumKey($hklm,$key)
foreach ($subkey in $subkeys.sNames){
#Filter out hotfixes
if ($subkey -notmatch “KB*”)
{
$appName = ($wmi.GetStringValue($hklm,”$key\$subkey”,”DisplayName”)).sValue
$appVersion = ($wmi.GetStringValue($hklm,”$key\$subkey”,”DisplayVersion”)).sValue
$appVendor = ($wmi.GetStringValue($hklm,”$key\$subkey”,”Publisher”)).sValue
$appInstalldate = ($wmi.GetStringValue($hklm,”$key\$subkey”,”InstallDate”)).sValue
#Format installation date if it exists
#Set a trap to catch exceptions thrown by ParseExact if date is not in the expected format
Trap {
continue
}
if ($appInstalldate)
{
$appInstalldate = [datetime]::ParseExact($appInstallDate,’yyyyMMdd’,$null).Date.ToShortDateString()
}
$objApps = New-Object System.Object | Add-Member NoteProperty Name $appName -PassThru | Add-Member NoteProperty Version $appVersion -PassThru | Add-Member NoteProperty Vendor $appVendor -PassThru | Add-Member NoteProperty “Install Date” $appInstalldate -PassThru
$colApps += $objApps
}
}
Write-Output “..Software (via registry)”
$MyReport += Get-CustomHeader “2″ “Software”
$MyReport += Get-HTMLTable $colApps
$MyReport += Get-CustomHeaderClose
Write-Output “..Software WMI class was not installed, used registry instead.”
Hi Alan, could I suggest having the Computer Description on the ‘General’ section. Would be nice for us as the computer name isn’t always very helpful.
Cheers mate.
Yes , Attachement as a Single HTML file also would hold good since we can schedule it as per convenience . For that i think we might need to remove the Error logs part since error logs might increase the Size of the HTML File that is being atatched and most organizations would have restrictions on the attachment size. Thanks Again for the Great Script !!
@Virtu-Al