OK so I am just finalizing an automated Citrix Server build process in work but need some help with a script/scripts. The old build process ran a script at the end of the build, to check server settings against server settings contained in an .xls file. Problem is that because excel wasn't on a newly built server, psexec was used to run the script on a remote machine. Psexec has now been banned in our Company so the script needs to be re-written. Problem is I don't know where to start!
How the script works: dserveraudit.bat uses psexec to run local-audit.ps1 remotely, and gets it's audit input setting (reg keys, reg values, files, print drivers, local groups) from auditinput6.5.xls. The script finishes by outputting an "exceptions" .xml which lists any missing settings on the new server.
I would like to do 2 things:
1) Get rid of the need for excel and use xml for input and output files. Can anyone help with this?
2) The script seems rather long to me. If anyone has any suggestions on how it can be "streamlined" or made more efficient then I am open to any suggestions.
I've also zipped the files Script Files
###############################
# dserveraudit.bat
###############################
CMD /c
Start/wait D:\Scripts\localAudit\psexec.exe /accepteula \\b0185-wts0111-t -u %2 -p %3 cmd /c "echo . | powershell -noprofile -executionpolicy Bypass d:\Scripts\LocalAudit\local-audit.ps1 \\ad\citrix\Xenapp6\ServerAudit\ERD\Scripts\localAudit\auditinput6.5.xls %1"
ECHO Y | Del "D:\Scripts\localAudit\psexec.exe"
ECHO Y | Del "D:\Scripts\localAudit\DServerAudit.bat"
###############################
# local-audit.ps1
###############################
param([string]$templatefile = "LocalAuditInput.xls",[string]$servertoaudit = $ENV:COMPUTERNAME)
##
##Server Audit Script
##
$timestamp = get-date -displayhint time
Write-Host "Execution started : " $timestamp
Set-Location d:\scripts\LocalAudit
$random = get-random
$tempfilename = ".\" + $random + "_LocalAuditInput.xls"
Copy-Item $templatefile $tempfilename -WarningAction SilentlyContinue
Write-Host "Template:" $templatefile "Server:" $servertoaudit
#######################################
##
##Functions
##
#######################################
###############################################################################
# Function: Test-RegSubKey
# Description: Test the existence of the registry key
# Return Value: True/false respectively
function Test-RegSubKey{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){$false} else {$true}
}
###############################################################################
# Function: Test-RegValue
# Description: Test the existence of the registry value
# Return Value: True/false respectively
function Test-RegValue{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){
write-error "The specified registry key does not exist.";
return "The specified registry key does not exist.";
}
$regVal=$subKey.GetValue($valueName);
if(!$regVal){$false} else {$true}
}
##############################################################################
## Get Registry String value
##
function Get-RegString{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName,
[object]$defaultValue="Reg Value not found"
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){
write-error "The specified registry key does not exist.";
return "The specified registry key does not exist.";
}
$subKey.GetValue($valueName,$defaultValue);
}
###############################################################################
# Function: Get-RegBinary
# Description: Gets the registry value (REG_BINARY)
# Return Value: Array object
function Get-RegBinary{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName,
[object]$defaultValue="Reg Value not found"
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
$subKey.GetValue($valueName,$defaultValue);
}
###############################################################################
# Function: Get-RegDWord
# Description: Gets the registry value (REG_DWORD)
# Return Value: registry dword value
function Get-RegDWord{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName,
[object]$defaultValue="Reg Value not found"
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){
write-error "The specified registry key does not exist.";
return;
}
$subKey.GetValue($valueName,$defaultValue);
}
###############################################################################
# Function: Get-RegMultipleString
# Description: Gets an array strings (REG_MULTI_SZ)
# Return Value: Array object
function Get-RegMultipleString{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName,
[object]$defaultValue="Reg Value not found"
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){
write-error "The specified registry key does not exist.";
return;
}
$subKey.GetValue($valueName,$defaultValue);
}
###############################################################################
# Function: Get-RegValueKind
# Description: Get the registry value type (e.g, string,dword etc)
# Return Value: None
function Get-RegValueKind{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){
write-error "The specified registry key does not exist.";
return;
}
$regVal=$subKey.GetValueKind($valueName);
if(!$regVal){
write-error "The specified registry value does not exist.";
return;
} else {
$regVal;
}
}
###############################################################################
# Function: Test-RegValue
# Description: Test the existence of the registry value
# Return Value: True/false respectively
function Test-RegValue{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){
write-error "The specified registry key does not exist.";
return;
}
$regVal=$subKey.GetValue($valueName);
if(!$regVal){$false} else {$true}
}
################################################################################
## Calculates the hash of a file and returns it as a string.
function Get-MD5([string]$UNCpath){
[string]$Content = Get-Content $UNCpath
$cryptoServiceProvider = [System.Security.Cryptography.MD5CryptoServiceProvider];
$hashAlgorithm = new-object $cryptoServiceProvider
$bytes = [System.Text.Encoding]::Default.GetBytes($Content)
$hashByteArray = $hashAlgorithm.ComputeHash($bytes);
$formattedHash = [string]::join(" ",($hashByteArray | foreach {$_.tostring("X2")}))
return $formattedHash;
}
################################################################################
## Retrieves a printer driver list from the server, returns a collection
function Get-PrintDriverList([string]$comp){
$driverlist = new-Object System.Collections.ArrayList
$driverlist = get-wmiobject -class "Win32_PrinterDriver" -namespace "root\CIMV2" -computername $comp
return $driverlist;
}
################################################################################
## Retrieves group members for a given local server group
function Get-LocalGroupMembers([string]$comp, [string]$GroupName){
$MemberNames = @()
$TempMemberNames = @()
$Group= [ADSI]"WinNT://$comp/$GroupName,group"
$Members = @($Group.psbase.Invoke("Members"))
$Members | ForEach-Object {$TempMemberNames += $_.GetType().InvokeMember("AdsPath", ‘GetProperty’, $null, $_, $null)}
$TempMemberNames | ForEach-Object {
$tempstr = $_.Split('/')
[string]$domainname = $tempstr[$tempstr.Count - 2].ToUpper()
[string]$username = $tempstr[$tempstr.Count - 1]
if ($domainname -eq $comp.ToUpper()) {$tempmember = $username} else {$tempmember = $domainname + "\" + $username}
$MemberNames += $tempmember
}
return $membernames
}
################################################################################
## Check if file's locked
function FileIsLocked( [string] $filePath ){
$script:locked = $false
$fileInfo = New-Object System.IO.FileInfo $filePath
trap
{
# if we are in here, the file is locked
$script:locked = $true;
continue;
}
$fileStream = $fileInfo.Open( [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::Read, [System.IO.FileShare]::None )
if ($fileStream) {$fileStream.Close()}
$script:locked
}
##########################################
##
##Main Sub
##
# Define Input filename
#[string]$excelfile = $PWD
#$excelfile = $excelfile + "\LocalAuditInput.xls"
$excelfile = $tempfilename
$EF = New-Object -comobject Excel.Application
$EF.DefaultFilePath = pwd
#$EF.Visible = $True
$EF.Workbooks.Open($tempfilename) |Out-Null
$ServerSheet = $EF.Worksheets.Item("Serverlist")
$RegKeysSheet = $EF.Worksheets.Item("Reg_Keys_To_Audit")
$RegValuesSheet = $EF.Worksheets.Item("Reg_Values_To_Audit")
$FileSheet = $EF.Worksheets.Item("Files_To_Audit")
$PrintDriversSheet = $EF.Worksheets.Item("PrinterDrivers_To_Audit")
$LocalGroupsSheet = $EF.Worksheets.Item("LocalGroups_To_Audit")
$xml = New-Object xml
$xml = [xml] (Get-Content "template.xml")
#$root = $xml.CreateElement("IDPCitrix")
#[void]$xml.AppendChild($root)
$xmltimestamp = $xml.CreateElement("AuditStartTime")
$xmltimestamp.PSBase.InnerText = (get-date)
[void]$xml["IDPCitrix"].AppendChild($xmltimestamp)
$Audit = "TEMPLATE"
###############################################################################
## Get a list of servers from the "Serverlist" sheet in the input file
##
## Iterate through rows, stopping at the first blank in col 1
$row = 2
$serverlist = new-Object System.Collections.ArrayList
#while ($ServerSheet.Cells.Item($row,1).Text -ne "")
# {
#$serverlist.Add($ServerSheet.Cells.Item($row,1).Text) |Out-Null
# #write-host "Loaded Server: " $ServerSheet.Cells.Item($row,1).Text
# $row += 1
# }
$serverlist.Add($servertoaudit) |Out-Null
#Write-Host "A total of " $serverlist.Count " servers will be audited"
#Write-Host "Server:" $Serverlist
## Read in all printer drivers to check
$templatedriverlist = new-Object System.Collections.ArrayList
$row = 2
while ($PrintDriversSheet.Cells.Item($row,1).Text -ne "")
{
[string]$tempdriver = $PrintDriversSheet.Cells.Item($row,1).Text
$templatedriverlist.Add($tempdriver) | Out-Null
$row += 1
}
## Find Audit Row
$col = 1
while ($RegKeysSheet.Cells.Item(1,$col).Text -ne ""){
if ($RegKeysSheet.Cells.Item(1,$col).Text -eq $Audit){
$RegKeyAuditCol = $col
}
$col += 1
}
$col = 1
while ($RegValuesSheet.Cells.Item(1,$col).Text -ne ""){
if ($RegValuesSheet.Cells.Item(1,$col).Text -eq $Audit){
$RegValuesAuditCol = $col
}
$col += 1
}
$col = 1
while ($FileSheet.Cells.Item(1,$col).Text -ne ""){
if ($FileSheet.Cells.Item(1,$col).Text -eq $Audit){
$FilesAuditCol = $col
}
$col += 1
}
##############################################################################
## Iterate through all servers
##
$serverstogo = $serverlist.Count
trap{
continue
}
@(foreach($comp in $serverlist)
{
$timestamp = get-date -displayhint time
Write-Host "Processing server : " $comp " Time: " $timestamp
$myobj = New-Object PSObject
$myobj | Add-Member NoteProperty Name $comp
$myobj | Add-Member NoteProperty Found "No"
trap{
continue
}
$root = $xml.IDPCitrix
$Record = $xml.CreateElement("ServerAudit")
[void]$xml["IDPCitrix"].AppendChild($Record)
$Name = $xml.CreateElement("ServerName")
$Name.PSBase.InnerText = $comp
[void]$Record.AppendChild($name)
$Date = $xml.CreateElement("AuditStartTime")
$Date.PSBase.InnerText = (get-date)
[void]$Record.AppendChild($date)
$pingStatus = gwmi Win32_PingStatus -Filter "Address='$comp'"
If($pingStatus.StatusCode -eq 0)
{
$myobj.Found = "Yes"
## Update XML Found
$Pingable = $xml.CreateElement("Pingable")
$Pingable.PSBase.InnerText = "Yes"
[void]$Record.AppendChild($Pingable)
$root = $xml.IDPCitrix.ServerAudit
$node = $xml.selectSingleNode("/IDPCitrix/ServerAudit[ServerName = '$comp' ]")
$Record = $xml.CreateElement("RegKeyAudit")
[void]$node.AppendChild($record)
$Record = $xml.CreateElement("RegValueAudit")
[void]$node.AppendChild($record)
$Record = $xml.CreateElement("FileAudit")
[void]$node.AppendChild($record)
$Record = $xml.CreateElement("PrintDriverAudit")
[void]$node.AppendChild($record)
$Record = $xml.CreateElement("LocalGroupsAudit")
[void]$node.AppendChild($record)
## Process all Registry Keys
Write-Host "Auditing Registry Keys" (get-date)
## Create XML RegKeyAudit
$node = $xml.selectSingleNode("/IDPCitrix/ServerAudit[ServerName = '$comp' ]/RegKeyAudit")
$row = 2
while ($RegKeysSheet.Cells.Item($row,1).Text -ne "")
{
[string]$outcol = $RegKeysSheet.Cells.Item($row,2).Text
$tempkey = $RegKeysSheet.Cells.Item($row,1).Text.Split('\')
[string]$localhive = $tempkey[0]
[string]$regtocheck = $RegKeysSheet.Cells.Item($row,1).Text
$regtocheck = $regtocheck.TrimStart($localhive)
$regtocheck = $regtocheck.TrimStart('\')
switch ($localhive)
{
"HKEY_LOCAL_MACHINE" { $localhive = "LocalMachine" }
"HKEY_CLASSES_ROOT" { $localhive = "ClassesRoot" }
"HKEY_CURRENT_CONFIG" { $localhive = "CurrentConfig" }
"HKEY_CURRENT_USER" { $localhive = "CurrentUser" }
"HKEY_PERFORMANCE_DATA" { $localhive = "PerformanceData" }
"HKEY__USERS" { $localhive = "Users" }
default { $localhive = "LocalMachine"}
}
[string]$keyfound = Test-RegSubKey $comp $localhive $regtocheck
#$myobj | Add-Member NoteProperty $outcol $keyfound
$keytemp = $RegKeysSheet.Cells.Item($row,$RegKeyAuditCol).Text
If ($keytemp -ne $keyfound)
{
$Record = $xml.CreateElement("RegKeyException")
$XMLRegCheck = $xml.CreateElement("KeyChecked")
$XMLRegCheck.PSBase.InnerText = $RegKeysSheet.Cells.Item($row,1).Text
$XMLRegCheckResult = $xml.CreateElement("KeyCheckResult")
$XMLRegCheckResult.PSBase.InnerText = $keyfound
$XMLRegCHeckTemplate = $xml.CreateElement("KeyCheckTemplate")
$XMLRegCHeckTemplate.PSBase.InnerText = $keytemp
$XMLRegCheckCat = $xml.CreateElement("KeyCheckCategory")
$XMLRegCheckCat.PSBase.InnerText = $RegKeysSheet.Cells.Item($row,3).Text
$XMLRegCheckDesc = $xml.CreateElement("KeyCheckDescription")
$XMLRegCheckDesc.PSBase.InnerText = $RegKeysSheet.Cells.Item($row,4).Text
[void]$Record.AppendChild($XMLRegCheck)
[void]$Record.AppendChild($XMLRegCheckResult)
[void]$Record.AppendChild($XMLRegCHeckTemplate)
[void]$Record.AppendChild($XMLRegCheckCat)
[void]$Record.AppendChild($XMLRegCheckDesc)
[void]$node.AppendChild($Record)
}
#write-host "Processed RegKey : " $RegKeysSheet.Cells.Item($row,1).Text
$row += 1
}
## Process all Registry Values
Write-Host "Auditing Registry Values" (get-date)
$node = $xml.selectSingleNode("/IDPCitrix/ServerAudit[ServerName = '$comp' ]/RegValueAudit")
$row = 2
while ($RegValuesSheet.Cells.Item($row,1).Text -ne "")
{
trap{
continue
}
[string]$outcol = $RegValuesSheet.Cells.Item($row,3).Text
[string]$regvaltocheck = $RegValuesSheet.Cells.Item($row,2).Text
$tempkey = $RegValuesSheet.Cells.Item($row,1).Text.Split('\')
[string]$localhive = $tempkey[0]
[string]$regtocheck = $RegValuesSheet.Cells.Item($row,1).Text
$regtocheck = $regtocheck.TrimStart($localhive)
$regtocheck = $regtocheck.TrimStart('\')
switch ($localhive)
{
"HKEY_LOCAL_MACHINE" { $localhive = "LocalMachine" }
"HKEY_CLASSES_ROOT" { $localhive = "ClassesRoot" }
"HKEY_CURRENT_CONFIG" { $localhive = "CurrentConfig" }
"HKEY_CURRENT_USER" { $localhive = "CurrentUser" }
"HKEY_PERFORMANCE_DATA" { $localhive = "PerformanceData" }
"HKEY__USERS" { $localhive = "Users" }
default { $localhive = "LocalMachine"}
}
$regvaluekind = Get-RegValueKind $comp $localhive $regtocheck $regvaltocheck
switch ($regvaluekind)
{
"DWORD" { $regvaluefound = Get-RegDWord $comp $localhive $regtocheck $regvaltocheck }
"String" { $regvaluefound = Get-RegString $comp $localhive $regtocheck $regvaltocheck }
"MultiString" { $regvaluefound = Get-RegMultipleString $comp $localhive $regtocheck $regvaltocheck }
default { $regvaluefound = "Registry value was not found"}
}
#$myobj | Add-Member NoteProperty $outcol $regvaluefound
$regvaltemp = $RegValuesSheet.Cells.Item($row,$RegValuesAuditCol).Text
if ($regvaltemp -ine $regvaluefound)
{
$Record = $xml.CreateElement("RegValueException")
$XMLRegValueKeyCheck = $xml.CreateElement("RegKeyChecked")
$XMLRegValueKeyCheck.PSBase.InnerText = $RegValuesSheet.Cells.Item($row,1).Text
$XMLRegValueCheck = $xml.CreateElement("RegValueChecked")
$XMLRegValueCheck.PSBase.InnerText = $regvaltocheck
$XMLRegValueCheckResult = $xml.CreateElement("RegValueDiscovered")
$XMLRegvalueCheckResult.PSBase.InnerText = $regvaluefound
$XMLRegValueCheckTemplate = $xml.CreateElement("RegValueTemplate")
$XMLRegValueCheckTemplate.PSBase.InnerText = $regvaltemp
$XMLRegValueCheckCat = $xml.CreateElement("RegValueCategory")
$XMLRegvalueCheckCat.PSBase.InnerText = $RegValuesSheet.Cells.Item($row,4).Text
$XMLRegValueCheckDesc = $xml.CreateElement("RegValueDescription")
$XMLRegvalueCheckDesc.PSBase.InnerText = $RegValuesSheet.Cells.Item($row,5).Text
[void]$Record.AppendChild($XMLRegValueKeyCheck)
[void]$Record.AppendChild($XMLRegValueCheck)
[void]$Record.AppendChild($XMLRegValueCheckResult)
[void]$Record.AppendChild($XMLRegValueCheckTemplate)
[void]$Record.AppendChild($XMLRegValueCheckCat)
[void]$Record.AppendChild($XMLRegValueCheckDesc)
[void]$node.AppendChild($Record)
}
#write-host "Processed RegValue : " $RegValuesSheet.Cells.Item($row,1).Text "\" $regvaltocheck " Value: " $regvaluefound
$row += 1
}
## Process all Files
Write-Host "Auditing Files" (get-date)
$node = $xml.selectSingleNode("/IDPCitrix/ServerAudit[ServerName = '$comp' ]/FileAudit")
$row = 2
while ($FileSheet.Cells.Item($row,1).Text -ne "")
{
[string]$outcol = $FileSheet.Cells.Item($row,2).Text
$tempPath = $FileSheet.Cells.Item($row,1).Text
$tempPath2 = $tempPath.Split(':')
[string]$UNCpath = "\\" + $comp + "\" + $tempPath2[0] + "$" + $tempPath2[1]
if (fileislocked($UNCpath))
{
$myfilehash = "File not found or locked"
}
else
{
[string]$myfilehash = Get-MD5 $UNCpath
}
#$myobj | Add-Member NoteProperty $outcol $myfilehash
$filechecktemp = $FileSheet.Cells.Item($row,$FilesAuditCol).Text
if ($filechecktemp -ne $myfilehash)
{
$Record = $xml.CreateElement("FileException")
$FileCheck = $xml.CreateElement("FileChecked")
$FileCheck.PSBase.InnerText = $FileSheet.Cells.Item($row,1).Text
$FileCheckResult = $xml.CreateElement("FileMD5Hash")
$FileCheckResult.PSBase.InnerText = $myfilehash
$FileCheckTemplate = $xml.CreateElement("TemplateMD5Hash")
$FileCheckTemplate.PSBase.InnerText = $filechecktemp
$FileCheckCat = $xml.CreateElement("FileCheckCategory")
$FileCheckCat.PSBase.InnerText = $FileSheet.Cells.Item($row,3).Text
$FileCheckDesc = $xml.CreateElement("FileCheckDescription")
$FileCheckDesc.PSBase.InnerText = $FileSheet.Cells.Item($row,4).Text
[void]$Record.AppendChild($FileCheck)
[void]$Record.AppendChild($FileCheckResult)
[void]$Record.AppendChild($FileCheckTemplate)
[void]$Record.AppendChild($FileCheckCat)
[void]$Record.AppendChild($FileCheckDesc)
[void]$node.AppendChild($Record)
}
#write-host "Processed file : " $UNCpath " MD5 Hash: " $myfilehash
$row += 1
}
## Process all Printer Drivers
Write-Host "Auditing Printer Drivers" (get-date)
$node = $xml.selectSingleNode("/IDPCitrix/ServerAudit[ServerName = '$comp' ]/PrintDriverAudit")
$discDriverList = Get-PrintDriverList $comp
## Process missing drivers
foreach ($objItem in $discDriverList){
if ($templatedriverlist -notcontains $objItem.Name){
#$objItem.Name extra driver found (unapproved driver found)
#write-host "Unapproved driver found: " $objItem.Name
$Record = $xml.CreateElement("PrintDriverException")
$DriverExceptionType = $xml.CreateElement("ExceptionType")
$DriverExceptionType.PSBase.InnerText = "Unapproved driver"
$OffendingDriver = $xml.CreateElement("OffendingDriver")
$OffendingDriver.PSBase.InnerText = $objItem.Name
[void]$Record.AppendChild($DriverExceptionType)
[void]$Record.AppendChild($OffendingDriver)
[void]$node.AppendChild($Record)
}
}
foreach ($templatedriver in $templatedriverlist){
[boolean]$driverfound = $false
foreach ($objItem in $discDriverList){
if ($templatedriver -eq $objItem.Name) {
$driverfound = $true
}
}
if ($driverfound -eq $false){
#$templatedriver is not on the server
#write-host "Template driver is not on the server: " $templatedriver
$Record = $xml.CreateElement("PrintDriverException")
$DriverExceptionType = $xml.CreateElement("ExceptionType")
$DriverExceptionType.PSBase.InnerText = "Driver not found"
$OffendingDriver = $xml.CreateElement("OffendingDriver")
$OffendingDriver.PSBase.InnerText = $templatedriver
[void]$Record.AppendChild($DriverExceptionType)
[void]$Record.AppendChild($OffendingDriver)
[void]$node.AppendChild($Record)
}
}
## Process all Local Groups
Write-Host "Auditing Local Groups" (get-date)
$node = $xml.selectSingleNode("/IDPCitrix/ServerAudit[ServerName = '$comp' ]/LocalGroupsAudit")
$col = 1
while ($LocalGroupsSheet.Cells.Item(1,$col).Text -ne "")
{
[string]$GroupName = $LocalGroupsSheet.Cells.Item(1,$col).Text
$discGroupMembers = Get-LocalGroupMembers $comp $GroupName
$tempGroupMembers = new-Object System.Collections.ArrayList
$row = 2
[string]$zzz = ""
while ($LocalGroupsSheet.Cells.Item($row,$col).Text -ne ""){
$zzz = $LocalGroupsSheet.Cells.Item($row,$col).Text
$tempGroupMembers.Add($zzz) | Out-Null
$row += 1
}
## Process Groups
foreach ($objItem in $discGroupMembers){
if ($tempGroupMembers -notcontains $objItem){
# Extra group member found (unapproved member)
#write-host "Extra group member found. Group: " $GroupName " Member: " $objItem
$Record = $xml.CreateElement("GroupAuditException")
$GroupAudited = $xml.CreateElement("GroupChecked")
$GroupAudited.PSBase.InnerText = $GroupName
$GroupExceptionType = $xml.CreateElement("GroupExceptionType")
$GroupExceptionType.PSBase.InnerText = "Unapproved group member found"
$OffendingGroup = $xml.CreateElement("OffendingGroup")
$OffendingGroup.PSBase.InnerText = $objItem
[void]$Record.AppendChild($GroupAudited)
[void]$Record.AppendChild($GroupExceptionType)
[void]$Record.AppendChild($OffendingGroup)
[void]$node.AppendChild($Record)
}
}
foreach ($tempGroupMember in $tempGroupMembers){
[boolean]$groupmemberfound = $false
foreach ($objItem in $discGroupMembers){
if ($tempGroupMember -eq $objItem) {
$groupmemberfound = $true
}
}
if ($groupmemberfound -eq $false){
# Required groupmember is not in the local server group
#write-host "Required groupmember is not in the local server group. Group: " $GroupName "Member: " $tempGroupMember
$Record = $xml.CreateElement("GroupAuditException")
$GroupAudited = $xml.CreateElement("GroupChecked")
$GroupAudited.PSBase.InnerText = $GroupName
$GroupExceptionType = $xml.CreateElement("GroupExceptionType")
$GroupExceptionType.PSBase.InnerText = "Local group is missing a required member"
$OffendingGroup = $xml.CreateElement("OffendingGroup")
$OffendingGroup.PSBase.InnerText = $tempGroupMember
[void]$Record.AppendChild($GroupAudited)
[void]$Record.AppendChild($GroupExceptionType)
[void]$Record.AppendChild($OffendingGroup)
[void]$node.AppendChild($Record)
}
}
$col += 1
}
$serverstogo -= 1
Write-Host "Completed " $comp " server audit. Servers left to go: " $serverstogo
#$myobj
}
}) #| export-Csv output.csv -noType;
$EF.Quit()
$xmltimestamp = $xml.CreateElement("AuditEndTime")
$xmltimestamp.PSBase.InnerText = (get-date)
[void]$xml.IDPCitrix.AppendChild($xmltimestamp)
$xmldate = Get-Date
[string]$xmlfilename = "Audit_{0}{1:d2}{2:d2}_{3:d2}{4:d2}" -f $xmldate.year,$xmldate.month,$xmldate.day,$xmldate.hour,$xmldate.minute
$xmlfilename = $servertoaudit + "_" + $xmlfilename + ".xml"
$xmlfile = "\\" + $servertoaudit + "\D$\Scripts\localAudit\" + $XmlfileName
$xml.save($xmlfile)
$reportname = "\\ad\citrix\Reports\Build\" + $xmlfilename
$xmlfilename = "D:\Scripts\LocalAudit\" + $xmlfilename
$xml.save($xmlfilename)
$timestamp = get-date -displayhint time
Copy-Item $xmlfilename \\ad\citrix\Reports\Build -WarningAction SilentlyContinue
#$FileDest = "\\" + $servertoaudit + "\D$\Scripts\localAudit"
#Copy-Item $xmlfilename $FileDest
#Copy-item $reportname $FileDest
Write-Host "Audit ended : " $timestamp
Write-Host "Network report name:" $reportname
Remove-Item $tempfilename -WarningAction SilentlyContinue
Write-Host "Local report name:" $xmlfilename
#[string]$ietemp = pwd
#$ietemp = $ietemp + "\" + $xmlfilename
#$ie = new-object -comobject "InternetExplorer.Application"
#$ie.visible = $true
#$ie.navigate($ietemp)