Exchange WMI Audit

I recently needed to automate my Exchange 2003 server daily checks. I have done some basic work on this before, but I really needed to automate the process and write the results to HTML to make it more “manager friendly”.

While searching the web for something I could use as a basic start up script, I came across an awesome script on Virtual-Al. This script uses WMI to audit a list of remote computers, and reports in a very neat HTML format. It was exactly the platform I needed, and it meant not having to re-invent the wheel.

I did however have some trouble with WMI and the mailbox stores, and finding a method for reporting the number of users and whether the store is mounted or not. I managed to find a workaround for the number of users, but it seems that checking the store status would have to be done with CDOEXM. This felt like a little too much effort as we are in the middle of our migration to Exchange 2007.

Speaking of Exchange 2007. The script cannot be used against Exchange 2007 servers, as Exchange 2007 does not include any WMI providers.
I am however working on an Exchange 2007 version or an Exchange version check process for this script. All credit for the HTML template and the original script should go to Alan Renouf, I merely took a great script and adapted it for use with Exchange.

The script will show only Exchange related information on the report, this includes Hotfixes, Services and Event Log entries. The version of the script which I use myself, creates an HTML menu, with a list of all of the servers processed and links to their individual reports. It also moves the files to a web server, which makes it much more automated. Comments and suggestions are always welcome.

This script is not displayed in a code window, but can be downloaded from here:

Update Network Interface Card parameters using WMI

The following little function can be used if you need to manually override DNS and WINS addresses on a list of remote computers, where they may have already obtained addresses from a DHCP server. The code gets a list of IP enabled NICs from a remote computer using WMI, you can list the servers in servers.txt file in the same folder. The script updates your DNS servers search list to add two manual entries and also adds two manual WINS servers. I had some fun the SetWINSServer method as it only accepts the variable as an array. Finally, the script modifies the registry, to create a DNS suffix search list. Although this script only modifies limited parameters, it can easilly be adapted to update any of the other parameters.
function updateNIC {
$NICs = gwmi -computer $server Win32_NetworkAdapterConfiguration | where{$_.IPEnabled -eq “TRUE”}

foreach ($NIC in $NICs) {

$DNS=("1.1.1.1","2.2.2.2")
$WINS=@("1.1.1.1","2.2.2.2")
$DOMAIN="acme.com"

$NIC.SetDNSServerSearchOrder($DNS)
$NIC.SetDynamicDNSRegistration("TRUE")
$NIC.SetWINSServer($WINS[0],$WINS[1])
$NIC.SetDNSDomain($DOMAIN)

$baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $server)
$baseKey.OpenSubKey
$subKey=$baseKey.OpenSubKey("SYSTEM\CurrentControlSet\Services\Tcpip\Parameters",$true)
$subkey.SetValue('SearchList','acme.local,acme.com')

}
}
foreach($server in (gc .servers.txt)){
updateNIC
}
Here are some images of the results of the Advanced TCP/IP Settings page after running the script. Here is the WINS tab.

Audit the local Administrators group on a list of remote computers

This is a very basic script which collects a list of server names from a local text file called servers.txt. The script reports the list of users, sorted by server name to a local text file in the root of drive C. I am working on cleaning up the results, as currently the “Adspath” reports to the text file in the following format: WinNT://DOMAIN/COMPUTER/Administrator This was the only true distinction between local or domain users, as “Name” reports only the name of the user or group. So you are never really sure if it is a domain or local entry. Finally I need to enable the script to report its results to Excel or HTML.

$Result = @()

foreach($server in (gc .servers.txt)){

$computer = [ADSI](”WinNT://” + $server + “,computer”)
$Group = $computer.psbase.children.find(”Administrators”)

function getAdmins
{$members = $Group.psbase.invoke(”Members”) | %{$_.GetType().InvokeMember(”Adspath”, ‘GetProperty’, $null, $_, $null)}
$members}

$Result += $server
$Result += ( getAdmins )
$Result += " "
}

$Result > c:results.txt
Invoke-Item c:results.txt

I had a little extra time today, and managed to clean up the members using the -replace parameter, replace “DOMAIN” with your domain name. The updated code looks something like this:

$Result = @()

foreach($server in (gc .servers.txt)){

$computer = [ADSI](”WinNT://” + $server + “,computer”)
$Group = $computer.psbase.children.find(”Administrators”)

function getAdmins
{$members = ($Group.psbase.invoke(”Members”) | %{$_.GetType().InvokeMember(”Adspath”, ‘GetProperty’, $null, $_, $null)}) -replace ('WinNT://DOMAIN/' + $server + '/'), '' -replace ('WinNT://DOMAIN/', 'DOMAIN') -replace ('WinNT://', '')
$members}

$Result += Write-Output "SERVER: $server"
$Result += Write-Output ' '
$Result += ( getAdmins )
$Result += Write-Output '____________________________'
$Result += Write-Output ' '
}



$Result > c:results.txt

Invoke-Item c:results.txt

You can simply add another -replace (‘WinNT://DOMAIN/’, ‘DOMAIN’) for each domain in the system. I know its a little hack ‘n slash but it will do for now.