Powershell find details about server / workstations

We have been scoring the net in the quest for a powershell script so we can audit easily server specs , or workstation , both , or just a series of machines on a xls spreadsheet.

 

Here is the code. We arent claiming the glory for it ( Jesse Hamrick handy work quoted )

 

# ==============================================================================================
#
# Microsoft PowerShell Source File — Created with SAPIEN Technologies PrimalScript 2007
#
# NAME: Server/Workstation Inventory (CompInv_v2.ps1)
#
# AUTHOR: Jesse Hamrick
# DATE : 2/25/2009
# Web : www.PowerShellPro.com
# COMMENT: Script Inventories Computers and sends results to an excel file.
#
# ==============================================================================================

# ==============================================================================================
# Functions Section
# ==============================================================================================
# Function Name ‘WMILookup’ – Gathers info using WMI and places results in Excel
# ==============================================================================================
Function WMILookup {
foreach ($StrComputer in $colComputers){
$GenItems1 = gwmi Win32_ComputerSystem -Comp $StrComputer
$GenItems2 = gwmi Win32_OperatingSystem -Comp $StrComputer
$SysItems1 = gwmi Win32_BIOS -Comp $StrComputer
$SysItems2 = gwmi Win32_TimeZone -Comp $StrComputer
$SysItems3 = gwmi Win32_WmiSetting -Comp $StrComputer
$ProcItems1 = gwmi Win32_Processor -Comp $StrComputer
$MemItems1 = gwmi Win32_PhysicalMemory -Comp $StrComputer
$memItems2 = gwmi Win32_PhysicalMemoryArray -Comp $StrComputer
$DiskItems = gwmi Win32_LogicalDisk -Comp $StrComputer
$NetItems = gwmi Win32_NetworkAdapterConfiguration -Comp $StrComputer |`
where{$_.IPEnabled -eq “True”}

# Populate General Sheet(1) with information
foreach ($objItem in $GenItems1){
$Sheet1.Cells.Item($intRow, 1) = $StrComputer
Switch($objItem.DomainRole)
{
0{$Sheet1.Cells.Item($intRow, 2) = “Stand Alone Workstation”}
1{$Sheet1.Cells.Item($intRow, 2) = “Member Workstation”}
2{$Sheet1.Cells.Item($intRow, 2) = “Stand Alone Server”}
3{$Sheet1.Cells.Item($intRow, 2) = “Member Server”}
4{$Sheet1.Cells.Item($intRow, 2) = “Back-up Domain Controller”}
5{$Sheet1.Cells.Item($intRow, 2) = “Primary Domain Controller”}
default{“Undetermined”}
}
$Sheet1.Cells.Item($intRow, 3) = $objItem.Manufacturer
$Sheet1.Cells.Item($intRow, 4) = $objItem.Model
$Sheet1.Cells.Item($intRow, 5) = $objItem.SystemType
$Sheet1.Cells.Item($intRow, 6) = $objItem.NumberOfProcessors
$Sheet1.Cells.Item($intRow, 7) = $objItem.TotalPhysicalMemory / 1024 / 1024
}
foreach ($objItem in $GenItems2){
$Sheet1.Cells.Item($intRow, 8) = $objItem.Caption
$Sheet1.Cells.Item($intRow, 9) = $objItem.csdversion
}

#Populate Systems Sheet
foreach ($objItem in $SysItems1){
$Sheet2.Cells.Item($intRow, 1) = $StrComputer
$Sheet2.Cells.Item($intRow, 2) = $objItem.Name
$Sheet2.Cells.Item($intRow, 3) = $objItem.SMBIOSbiosVersion
$Sheet2.Cells.Item($intRow, 4) = $objItem.SerialNumber
}
foreach ($objItem in $SysItems2){
$Sheet2.Cells.Item($intRow, 5) = $objItem.Caption
}
foreach ($objItem in $SysItems3){
$Sheet2.Cells.Item($intRow, 6) = $objItem.BuildVersion
}

#Populate Processor Sheet
foreach ($objItem in $ProcItems1){
$Sheet3.Cells.Item($intRowCPU, 1) = $StrComputer
$Sheet3.Cells.Item($intRowCPU, 2) = $objItem.DeviceID+” “+$objItem.Name
$Sheet3.Cells.Item($intRowCPU, 3) = $objItem.Description
$Sheet3.Cells.Item($intRowCPU, 4) = $objItem.family
$Sheet3.Cells.Item($intRowCPU, 5) = $objItem.currentClockSpeed
$Sheet3.Cells.Item($intRowCPU, 6) = $objItem.l2cacheSize
$Sheet3.Cells.Item($intRowCPU, 7) = $objItem.UpgradeMethod
$Sheet3.Cells.Item($intRowCPU, 8) = $objItem.SocketDesignation
$intRowCPU = $intRowCPU + 1
}

#Populate Memory Sheet
$bankcounter = 1
foreach ($objItem in $memItems2){
$MemSlots = $objItem.MemoryDevices +1

foreach ($objItem in $MemItems1){
$Sheet4.Cells.Item($intRowMem, 1) = $StrComputer
$Sheet4.Cells.Item($intRowMem, 2) = “Bank ” +$bankcounter
if($objItem.BankLabel -eq “”){
$Sheet4.Cells.Item($intRowMem, 3) = $objItem.DeviceLocator}
Else{$Sheet4.Cells.Item($intRowMem, 3) = $objItem.BankLabel}
$Sheet4.Cells.Item($intRowMem, 4) = $objItem.Capacity/1024/1024
$Sheet4.Cells.Item($intRowMem, 5) = $objItem.FormFactor
$Sheet4.Cells.Item($intRowMem, 6) = $objItem.TypeDetail
$intRowMem = $intRowMem + 1
$bankcounter = $bankcounter + 1
}
while($bankcounter -lt $MemSlots)
{
$Sheet4.Cells.Item($intRowMem, 1) = $StrComputer
$Sheet4.Cells.Item($intRowMem, 2) = “Bank ” +$bankcounter
$Sheet4.Cells.Item($intRowMem, 3) = “is Empty”
$Sheet4.Cells.Item($intRowMem, 4) = “”
$Sheet4.Cells.Item($intRowMem, 5) = “”
$Sheet4.Cells.Item($intRowMem, 6) = “”
$intRowMem = $intRowMem + 1
$bankcounter = $bankcounter + 1
}
}

#Populate Disk Sheet
foreach ($objItem in $DiskItems){
$Sheet5.Cells.Item($intRowDisk, 1) = $StrComputer
Switch($objItem.DriveType)
{
2{$Sheet5.Cells.Item($intRowDisk, 2) = “Floppy”}
3{$Sheet5.Cells.Item($intRowDisk, 2) = “Fixed Disk”}
5{$Sheet5.Cells.Item($intRowDisk, 2) = “Removable Media”}
default{“Undetermined”}
}
$Sheet5.Cells.Item($intRowDisk, 3) = $objItem.DeviceID
$Sheet5.Cells.Item($intRowDisk, 4) = $objItem.Size/1024/1024
$Sheet5.Cells.Item($intRowDisk, 5) = $objItem.FreeSpace/1024/1024
$intRowDisk = $intRowDisk + 1
}

#Populate Network Sheet
foreach ($objItem in $NetItems){
$Sheet6.Cells.Item($intRowNet, 1) = $StrComputer
$Sheet6.Cells.Item($intRowNet, 2) = $objItem.Caption+” (enabled)”
$Sheet6.Cells.Item($intRowNet, 3) = $objItem.DHCPEnabled
$Sheet6.Cells.Item($intRowNet, 4) = $objItem.IPAddress
$Sheet6.Cells.Item($intRowNet, 5) = $objItem.IPSubnet
$Sheet6.Cells.Item($intRowNet, 6) = $objItem.DefaultIPGateway
$Sheet6.Cells.Item($intRowNet, 7) = $objItem.DNSServerSearchOrder
$Sheet6.Cells.Item($intRowNet, 8) = $objItem.FullDNSRegistrationEnabled
$Sheet6.Cells.Item($intRowNet, 9) = $objItem.WINSPrimaryServer
$Sheet6.Cells.Item($intRowNet, 10) = $objItem.WINSSecondaryServer
$Sheet6.Cells.Item($intRowNet, 11) = $objItem.WINSEnableLMHostsLookup
$intRowNet = $intRowNet + 1
}

$intRow = $intRow + 1
$intRowCPU = $intRowCPU + 1
$intRowMem = $intRowMem + 1
$intRowDisk = $intRowDisk + 1
$intRowNet = $intRowNet + 1
}
}

# ==============================================================================================
# Function Name ‘WMILookupCred’-Uses Alternative Credential-Gathers info using WMI.
# ==============================================================================================
Function WMILookupCred {
foreach ($StrComputer in $colComputers){
$GenItems1 = gwmi Win32_ComputerSystem -Comp $StrComputer -Credential $cred
$GenItems2 = gwmi Win32_OperatingSystem -Comp $StrComputer -Credential $cred
$SysItems1 = gwmi Win32_BIOS -Comp $StrComputer -Credential $cred
$SysItems2 = gwmi Win32_TimeZone -Comp $StrComputer -Credential $cred
$SysItems3 = gwmi Win32_WmiSetting -Comp $StrComputer -Credential $cred
$ProcItems1 = gwmi Win32_Processor -Comp $StrComputer -Credential $cred
$MemItems1 = gwmi Win32_PhysicalMemory -Comp $StrComputer -Credential $cred
$memItems2 = gwmi Win32_PhysicalMemoryArray -Comp $StrComputer -Credential $cred
$DiskItems = gwmi Win32_LogicalDisk -Comp $StrComputer -Credential $cred
$NetItems = gwmi Win32_NetworkAdapterConfiguration -Comp $StrComputer -Credential $cred |`
where{$_.IPEnabled -eq “True”}

# Populate General Sheet(1) with information
foreach ($objItem in $GenItems1){
$Sheet1.Cells.Item($intRow, 1) = $StrComputer
Switch($objItem.DomainRole)
{
0{$Sheet1.Cells.Item($intRow, 2) = “Stand Alone Workstation”}
1{$Sheet1.Cells.Item($intRow, 2) = “Member Workstation”}
2{$Sheet1.Cells.Item($intRow, 2) = “Stand Alone Server”}
3{$Sheet1.Cells.Item($intRow, 2) = “Member Server”}
4{$Sheet1.Cells.Item($intRow, 2) = “Back-up Domain Controller”}
5{$Sheet1.Cells.Item($intRow, 2) = “Primary Domain Controller”}
default{“Undetermined”}
}
$Sheet1.Cells.Item($intRow, 3) = $objItem.Manufacturer
$Sheet1.Cells.Item($intRow, 4) = $objItem.Model
$Sheet1.Cells.Item($intRow, 5) = $objItem.SystemType
$Sheet1.Cells.Item($intRow, 6) = $objItem.NumberOfProcessors
$Sheet1.Cells.Item($intRow, 7) = $objItem.TotalPhysicalMemory / 1024 / 1024
}
foreach ($objItem in $GenItems2){
$Sheet1.Cells.Item($intRow, 8) = $objItem.Caption
$Sheet1.Cells.Item($intRow, 9) = $objItem.csdversion
}

#Populate Systems Sheet
foreach ($objItem in $SysItems1){
$Sheet2.Cells.Item($intRow, 1) = $StrComputer
$Sheet2.Cells.Item($intRow, 2) = $objItem.Name
$Sheet2.Cells.Item($intRow, 3) = $objItem.SMBIOSbiosVersion
$Sheet2.Cells.Item($intRow, 4) = $objItem.SerialNumber
}
foreach ($objItem in $SysItems2){
$Sheet2.Cells.Item($intRow, 5) = $objItem.Caption
}
foreach ($objItem in $SysItems3){
$Sheet2.Cells.Item($intRow, 6) = $objItem.BuildVersion
}

#Populate Processor Sheet
foreach ($objItem in $ProcItems1){
$Sheet3.Cells.Item($intRowCPU, 1) = $StrComputer
$Sheet3.Cells.Item($intRowCPU, 2) = $objItem.DeviceID+” “+$objItem.Name
$Sheet3.Cells.Item($intRowCPU, 3) = $objItem.Description
$Sheet3.Cells.Item($intRowCPU, 4) = $objItem.family
$Sheet3.Cells.Item($intRowCPU, 5) = $objItem.currentClockSpeed
$Sheet3.Cells.Item($intRowCPU, 6) = $objItem.l2cacheSize
$Sheet3.Cells.Item($intRowCPU, 7) = $objItem.UpgradeMethod
$Sheet3.Cells.Item($intRowCPU, 8) = $objItem.SocketDesignation
$intRowCPU = $intRowCPU + 1
}

#Populate Memory Sheet
$bankcounter = 1
foreach ($objItem in $memItems2){
$MemSlots = $objItem.MemoryDevices +1

foreach ($objItem in $MemItems1){
$Sheet4.Cells.Item($intRowMem, 1) = $StrComputer
$Sheet4.Cells.Item($intRowMem, 2) = “Bank ” +$bankcounter
if($objItem.BankLabel -eq “”){
$Sheet4.Cells.Item($intRowMem, 3) = $objItem.DeviceLocator}
Else{$Sheet4.Cells.Item($intRowMem, 3) = $objItem.BankLabel}
$Sheet4.Cells.Item($intRowMem, 4) = $objItem.Capacity/1024/1024
$Sheet4.Cells.Item($intRowMem, 5) = $objItem.FormFactor
$Sheet4.Cells.Item($intRowMem, 6) = $objItem.TypeDetail
$intRowMem = $intRowMem + 1
$bankcounter = $bankcounter + 1
}
while($bankcounter -lt $MemSlots)
{
$Sheet4.Cells.Item($intRowMem, 1) = $StrComputer
$Sheet4.Cells.Item($intRowMem, 2) = “Bank ” +$bankcounter
$Sheet4.Cells.Item($intRowMem, 3) = “is Empty”
$Sheet4.Cells.Item($intRowMem, 4) = “”
$Sheet4.Cells.Item($intRowMem, 5) = “”
$Sheet4.Cells.Item($intRowMem, 6) = “”
$intRowMem = $intRowMem + 1
$bankcounter = $bankcounter + 1
}
}

#Populate Disk Sheet
foreach ($objItem in $DiskItems){
$Sheet5.Cells.Item($intRowDisk, 1) = $StrComputer
Switch($objItem.DriveType)
{
2{$Sheet5.Cells.Item($intRowDisk, 2) = “Floppy”}
3{$Sheet5.Cells.Item($intRowDisk, 2) = “Fixed Disk”}
5{$Sheet5.Cells.Item($intRowDisk, 2) = “Removable Media”}
default{“Undetermined”}
}
$Sheet5.Cells.Item($intRowDisk, 3) = $objItem.DeviceID
$Sheet5.Cells.Item($intRowDisk, 4) = $objItem.Size/1024/1024
$Sheet5.Cells.Item($intRowDisk, 5) = $objItem.FreeSpace/1024/1024
$intRowDisk = $intRowDisk + 1
}

#Populate Network Sheet
foreach ($objItem in $NetItems){
$Sheet6.Cells.Item($intRowNet, 1) = $StrComputer
$Sheet6.Cells.Item($intRowNet, 2) = $objItem.Caption+” (enabled)”
$Sheet6.Cells.Item($intRowNet, 3) = $objItem.DHCPEnabled
$Sheet6.Cells.Item($intRowNet, 4) = $objItem.IPAddress
$Sheet6.Cells.Item($intRowNet, 5) = $objItem.IPSubnet
$Sheet6.Cells.Item($intRowNet, 6) = $objItem.DefaultIPGateway
$Sheet6.Cells.Item($intRowNet, 7) = $objItem.DNSServerSearchOrder
$Sheet6.Cells.Item($intRowNet, 8) = $objItem.FullDNSRegistrationEnabled
$Sheet6.Cells.Item($intRowNet, 9) = $objItem.WINSPrimaryServer
$Sheet6.Cells.Item($intRowNet, 10) = $objItem.WINSSecondaryServer
$Sheet6.Cells.Item($intRowNet, 11) = $objItem.WINSEnableLMHostsLookup
$intRowNet = $intRowNet + 1
}

$intRow = $intRow + 1
$intRowCPU = $intRowCPU + 1
$intRowMem = $intRowMem + 1
$intRowDisk = $intRowDisk + 1
$intRowNet = $intRowNet + 1
}
}

# =============================================================================================
# Function Name ‘ListComputers’ – Enumerates ALL computer objects in AD
# ==============================================================================================
Function ListComputers {
$strCategory = “computer”

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = (“(objectCategory=$strCategory)”)

$colProplist = “name”
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

$colResults = $objSearcher.FindAll()

foreach ($objResult in $colResults)
{$objComputer = $objResult.Properties; $objComputer.name}
}

# ==============================================================================================
# Function Name ‘ListServers’ – Enumerates ALL Servers objects in AD
# ==============================================================================================
Function ListServers {
$strCategory = “computer”
$strOS = “Windows*Server*”

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = (“(&(objectCategory=$strCategory)(OperatingSystem=$strOS))”)

$colProplist = “name”
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

$colResults = $objSearcher.FindAll()

foreach ($objResult in $colResults)
{$objComputer = $objResult.Properties; $objComputer.name}
}

# ========================================================================
# Function Name ‘ListTextFile’ – Enumerates Computer Names in a text file
# Create a text file and enter the names of each computer. One computer
# name per line. Supply the path to the text file when prompted.
# ========================================================================
Function ListTextFile {
$strText = Read-Host “Enter the path for the text file”
$colComputers = Get-Content $strText
}

# ========================================================================
# Function Name ‘SingleEntry’ – Enumerates Computer from user input
# ========================================================================
Function ManualEntry {
$colComputers = Read-Host “Enter Computer Name or IP”
}

# ==============================================================================================
# Script Body
# ==============================================================================================
$erroractionpreference = “SilentlyContinue”
#Gather info from user.
Write-Host “********************************” -ForegroundColor Green
Write-Host “Computer Inventory Script” -ForegroundColor Green
Write-Host “By: Jesse Hamrick” -ForegroundColor Green
Write-Host “Created: 04/15/2009” -ForegroundColor Green
Write-Host “Contact: www.PowerShellPro.com” -ForegroundColor Green
Write-Host “********************************” -ForegroundColor Green
Write-Host ” ”
Write-Host “Admin rights are required to enumerate information.” -ForegroundColor Green
Write-Host “Would you like to use an alternative credential?” -ForegroundColor Green
$credResponse = Read-Host “[Y] Yes, [N] No”
If($CredResponse -eq “y”){$cred = Get-Credential DOMAINUSER}
Write-Host ” ”
Write-Host “Which computer resources would you like in the report?” -ForegroundColor Green
$strResponse = Read-Host “[1] All Domain Computers, [2] All Domain Servers, [3] Computer names from a File, [4] Choose a Computer manually”
If($strResponse -eq “1”){$colComputers = ListComputers | Sort-Object}
elseif($strResponse -eq “2”){$colComputers = ListServers | Sort-Object}
elseif($strResponse -eq “3”){. ListTextFile}
elseif($strResponse -eq “4”){. ManualEntry}
else{Write-Host “You did not supply a correct response, `
Please run script again.” -foregroundColor Red}
Write-Progress -Activity “Getting Inventory” -status “Running…” -id 1

#New Excel Application
$Excel = New-Object -Com Excel.Application
$Excel.visible = $True

# Create 6 worksheets
$Excel = $Excel.Workbooks.Add()
$Sheet = $Excel.Worksheets.Add()
$Sheet = $Excel.Worksheets.Add()
$Sheet = $Excel.Worksheets.Add()

# Assign each worksheet to a variable and
# name the worksheet.
$Sheet1 = $Excel.Worksheets.Item(1)
$Sheet2 = $Excel.WorkSheets.Item(2)
$Sheet3 = $Excel.WorkSheets.Item(3)
$Sheet4 = $Excel.WorkSheets.Item(4)
$Sheet5 = $Excel.WorkSheets.Item(5)
$Sheet6 = $Excel.WorkSheets.Item(6)
$Sheet1.Name = “General”
$Sheet2.Name = “System”
$Sheet3.Name = “Processor”
$Sheet4.Name = “Memory”
$Sheet5.Name = “Disk”
$Sheet6.Name = “Network”

#Create Heading for General Sheet
$Sheet1.Cells.Item(1,1) = “Device_Name”
$Sheet1.Cells.Item(1,2) = “Role”
$Sheet1.Cells.Item(1,3) = “HW_Make”
$Sheet1.Cells.Item(1,4) = “HW_Model”
$Sheet1.Cells.Item(1,5) = “HW_Type”
$Sheet1.Cells.Item(1,6) = “CPU_Count”
$Sheet1.Cells.Item(1,7) = “Memory_MB”
$Sheet1.Cells.Item(1,8) = “Operating_System”
$Sheet1.Cells.Item(1,9) = “SP_Level”

#Create Heading for System Sheet
$Sheet2.Cells.Item(1,1) = “Device_Name”
$Sheet2.Cells.Item(1,2) = “BIOS_Name”
$Sheet2.Cells.Item(1,3) = “BIOS_Version”
$Sheet2.Cells.Item(1,4) = “HW_Serial_#”
$Sheet2.Cells.Item(1,5) = “Time_Zone”
$Sheet2.Cells.Item(1,6) = “WMI_Version”

#Create Heading for Processor Sheet
$Sheet3.Cells.Item(1,1) = “Device_Name”
$Sheet3.Cells.Item(1,2) = “Processor(s)”
$Sheet3.Cells.Item(1,3) = “Type”
$Sheet3.Cells.Item(1,4) = “Family”
$Sheet3.Cells.Item(1,5) = “Speed_MHz”
$Sheet3.Cells.Item(1,6) = “Cache_Size_MB”
$Sheet3.Cells.Item(1,7) = “Interface”
$Sheet3.Cells.Item(1,8) = “#_of_Sockets”

#Create Heading for Memory Sheet
$Sheet4.Cells.Item(1,1) = “Device_Name”
$Sheet4.Cells.Item(1,2) = “Bank_#”
$Sheet4.Cells.Item(1,3) = “Label”
$Sheet4.Cells.Item(1,4) = “Capacity_MB”
$Sheet4.Cells.Item(1,5) = “Form”
$Sheet4.Cells.Item(1,6) = “Type”

#Create Heading for Disk Sheet
$Sheet5.Cells.Item(1,1) = “Device_Name”
$Sheet5.Cells.Item(1,2) = “Disk_Type”
$Sheet5.Cells.Item(1,3) = “Drive_Letter”
$Sheet5.Cells.Item(1,4) = “Capacity_MB”
$Sheet5.Cells.Item(1,5) = “Free_Space_MB”

#Create Heading for Network Sheet
$Sheet6.Cells.Item(1,1) = “Device_Name”
$Sheet6.Cells.Item(1,2) = “Network_Card”
$Sheet6.Cells.Item(1,3) = “DHCP_Enabled”
$Sheet6.Cells.Item(1,4) = “IP_Address”
$Sheet6.Cells.Item(1,5) = “Subnet_Mask”
$Sheet6.Cells.Item(1,6) = “Default_Gateway”
$Sheet6.Cells.Item(1,7) = “DNS_Servers”
$Sheet6.Cells.Item(1,8) = “DNS_Reg”
$Sheet6.Cells.Item(1,9) = “Primary_WINS”
$Sheet6.Cells.Item(1,10) = “Secondary_WINS”
$Sheet6.Cells.Item(1,11) = “WINS_Lookup”

$colSheets = ($Sheet1, $Sheet2, $Sheet3, $Sheet4, $Sheet5, $Sheet6)
foreach ($colorItem in $colSheets){
$intRow = 2
$intRowCPU = 2
$intRowMem = 2
$intRowDisk = 2
$intRowNet = 2
$WorkBook = $colorItem.UsedRange
$WorkBook.Interior.ColorIndex = 20
$WorkBook.Font.ColorIndex = 11
$WorkBook.Font.Bold = $True
}

If($credResponse -eq “y”){WMILookupCred}
Else{WMILookup}

#Auto Fit all sheets in the Workbook
foreach ($colorItem in $colSheets){
$WorkBook = $colorItem.UsedRange
$WorkBook.EntireColumn.AutoFit()
clear
}
Write-Host “*******************************” -ForegroundColor Green
Write-Host “The Report has been completed.” -ForeGroundColor Green
Write-Host “*******************************” -ForegroundColor Green
# ========================================================================
# END of Script
# ========================================================================

find all shares in a domain

We have been looking for a tool to find all the shares in a domain. It can be used to remove potential virus threats , or discover what is out there.

http://technet.microsoft.com/en-us/sysinternals/bb897442.aspx

VMware ESX network cloning

Ever wanted to clome your network settings across multiple ESX hosts ?

 

Execute this first :

Add-pssnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue

 

That adds in the relevant Powershell tools save you having to use PowerCLi

 

Then copy and paste this into a .ps1 file

 

$srvconnection = Connect-VIServer (Read-Host “Please enter the name of your VCenter SERVER”)
$sourceHost = Get-VMHost -Name (Read-Host “Enter the name of your existing server as seen in the VI Client Source:”)
$targetHost = Get-VMHost -Name (Read-Host “Enter the name of the server to configure as seen in the VI Target Client:”)

#Collecting source information
$sourceHostObj = Get-VMHost -Name $sourceHost -Server $srvconnection
write-host “Exporting vSwithes configurations from $sourceHost”
$sourcevSwitches = $sourceHostObj | Get-VirtualSwitch
write-host “Exporting Port Group configurations from $targetHost”
$sourcevPGs = $sourceHostObj | Get-VirtualPortGroup

#Collecting target host information
$targethostObj = Get-VMHost -Name $targetHost -Server $srvconnection
write-host “Exporting vSwithes configurations of target $targetHost”
$targetvSwitches = $targetHostObj | Get-VirtualSwitch
write-host “Exporting Port Group configurations of target $targetHost”
$targetvPGs = $targetHostObj | Get-VirtualPortGroup

# determine the difference
$differencevSwitches = Compare-Object $sourcevSwitches $targetvSwitches
$differencevPGs = Compare-Object $sourcevPGs $targetvPGs

# Only process the difference in vSwitches
$differencevSwitches | %{
$newvSwitch = $_.InputObject
Write-Host “Creating Virtual Switch $($newvSwitch.Name) on $targetHost”
if($newvSwitch.Nic) {
$outputvSwitch = $targethostObj | New-VirtualSwitch -Name $newvSwitch.Name -NumPorts $newvSwitch.NumPorts -Mtu $newvSwitch.Mtu -Nic $newvSwitch.Nic
} else {
$outputvSwitch = $targethostObj | New-VirtualSwitch -Name $newvSwitch.Name -NumPorts $newvSwitch.NumPorts -Mtu $newvSwitch.Mtu
}
}

# Only Process difference in Port Groups
$differencevPGs | %{
$newvPG = $_.InputObject
Write-Host “Creating Port group “”$($newvPG.Name)”” on vSwitch “”$($newvPG.VirtualSwitchName)”” on target host $targetHost”
$outputvPG = $targethostObj | Get-VirtualSwitch -Name $newvPG.VirtualSwitchName | New-VirtualPortGroup -Name $newvPG.Name-VLanId $newvPG.VLanID
}

 

 

Only thing to note is it creates the VMotion ports incorrectly , delete them and add them as a VMKernel port.

 

 

Servers pending reboots via WSUS and email

We have been working on a WSUS project , and its coming to a close. The client required information on which servers required rebooting to complete a patch.

We came up with this script

 

$csvfile=’drive WSUS Scriptsrebootpending.csv’
Try{
[void][reflection.assembly]::LoadWithPartialName(‘Microsoft.UpdateServices.Administration’)
$wsus=[Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer()
$computerScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope
$computerScope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::InstalledPendingReboot
$wsus.GetComputerTargets($computerScope) |
Select FullDomainName,IPAddress,RequestedTargetGroupName |
Export-Csv $csvfile -NoType

}
catch{
throw
}

$smtpServer = “your smtp server”
$msg = new-object Net.Mail.MailMessage
$att = new-object Net.Mail.Attachment($csvfile)
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = “your address”
$msg.To.Add(“your address”)
$msg.Subject = “pending reboots”
$msg.Body = “Check attachment:”,$messagebody
#”Here is todays copy for ”
$msg.Attachments.Add($att)
$smtp.Send($msg)
#$att.Dispose()

Usernames from Email exchange 365

If you have email addresses and need to get usernames ( this is for the cloud based exchange 365 ) :-

Open powershell and :

Import-Module ActiveDirectory

Also logon to Exchange environment Exchange 2010 in the cloud:-

#Logon

$LiveCred = Get-Credential

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection

Import-PSSession $Session

 

Then the script is:-

Get-Content emailtest.csv | %{

Get-Mailbox $_ | Select-Object PrimarySmtpAddress, UserPrincipalName

} | Export-Csv users.csv -NoTypeInformation

WSUS – machines go then come back ?

One of our engineers wrote this little rough and ready script that recreates the  AccountDomainSid and SUSClientID in the registry. This is caused often by VMs that have been cloned from a template.

 

Requirements are that PSEXEC is installed in the same directory as where the script is ran. We tend to create folder on the WSUS server and run it from there

@echo off

set /p a=”Enter IP Address or Name: please DO NOT include \”

psexec \%a% net stop wuauserv

psexec \%a% REG DELETE “HKLMSOFTWAREMicrosoftWindowsCurrentVersionWindowsUpdate” /v AccountDomainSid /f

psexec \%a% REG DELETE “HKLMSOFTWAREMicrosoftWindowsCurrentVersionWindowsUpdate” /v PingID /f

psexec \%a% REG DELETE “HKLMSOFTWAREMicrosoftWindowsCurrentVersionWindowsUpdate” /v SusClientId /f

psexec \%a% net start wuauserv

psexec \%a% wuauclt /resetauthorization /detectnow

psexec \%a% wuauclt /reportnow

echo…………………………………………………………..

echo Machine should reappear in approx 10 minutes.

pause

 

 

He also adapted one that will force a machine to detect and report its WSUS status to the WSUS server

 

@echo off

set /p a=”Enter IP Address or Name please DO NOT include \ : “

psexec \%a% net stop wuauserv

psexec \%a% net start wuauserv

rem psexec %a% wuauclt.exe /resetauthorization

psexec \%a% wuauclt.exe /detectnow

psexec \%a% wuauclt.exe /reportnow

cls

echo …………………………………………………………..

echo REPORT STATUS

echo ————–

echo A report and detectnow has been run on the machine you specified.

pause

GOTO MENU

Apple Airplay and Meru

GiraffeIT.com have found out that Meru and Apples airplay systems dont always play well together. Specifically, the configuration out of the box doesnt work at all.

We have found the following settings of use :

 

Log into the GUI
Click on the “Configuration” Tab
Click on “System Settings” under “Devices”
Click on “UDP Broadcast Up”
Click “Add”
Enter port number “5297″ click OK
Repeat to enter in port numbers “5298″ and “5353″
Click on “UDP Broadcast Down”
Click “Add”
Enter port number “5297″ click OK
Repeat to enter in port numbers “5298″ and “5353″
Click on the “Configuration” Tab
Click on “ESS” under “Wireless”
Select the relevant ESS profile and click “Settings”
Set the “Allow Multicast Flag” to “On”

Reset home folders

GiraffeIT have often been asked how to reset home folders. It can be quite time consuming if done manually on a range of users.

We have found, tested and sucessfully used the following scriptlet. Its a powershell script so dont forget to allow execution.

 

 

#############################################################################
# Script: Repair-HomeFolderPermissions.ps1
# Author: Chris Brown    http://www.flamingkeys.com
# Date: 20/10/2010
# Keywords:
# Comments:
# Pre-Requisites: Full Control over destination folder.
#
# +------------+-----+---------------------------------------------------------+
# |       Date | Usr | Description                                             |
# +------------+-----+---------------------------------------------------------+
# | 20/10/2010 | CJB | Initial Script                                          |
# | 28/09/2011 | CJB | Fixed flags issue                                       |
# +------------+-----+---------------------------------------------------------+
#
# DISCLAIMER
# ==========
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
# RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#############################################################################

# ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
#            Variables
#
# Where is the root of the home drives?
$homeDrivesDir="\uncofhomefolder"
# Report only? ($false = fix problems)
$reportMode = $false
# Print all valid directories?
$verbose = $false
# What domain are your users in?
$domainName = "something.internal"
#
# ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

# Save the current working directory before we change it (purely for convenience)
pushd .
# Change to the location of the home drives
set-location $homeDrivesDir

# Warn the user if we will be fixing or just reporting on problems
write-host ""

if ($reportMode) {
 Write-Host "Report mode is on. Not fixing problems"
} else {
 Write-Host "Report mode is off. Will fix problems"
}

write-host ""

# Initialise a few counter variables. Only useful for multiple executions from the same session
$goodPermissions = $unfixablePermissions = $fixedPermissions = $badPermissions = 0
$failedFolders = @()

# For every folder in the $homeDrivesDir folder
foreach($homeFolder in (Get-ChildItem $homeDrivesDir | Where {$_.psIsContainer -eq $true})) {

 # dump the current ACL in a variable
 $Acl = Get-Acl $homeFolder

 # create a permission mask in the form of DOMAINUsername where Username=foldername
 #    (adjust as necessary if your home folders are not exactly your usernames)
 $compareString = "*" + $domainName + "" + $homeFolder.Name + " Allow  FullControl*"

 # if the permission mask is in the ACL
 if ($Acl.AccessToString -like $compareString) {

 # everything's good, increment the counter and move on.
 if ($verbose) {Write-Host "Permissions are valid for" $homeFolder.Name -backgroundcolor green -foregroundcolor white}
 $goodPermissions += 1

 } else {
 # Permissions are invalid, either fix or report
 # increment the number of permissions needing repair
 $badPermissions += 1
 # if we're in report mode
 if ($reportMode -eq $true) {
 # reportmode is on, don't do anything
 Write-Host "Permissions not valid for" $homeFolder.Name -backgroundcolor red -foregroundcolor white
 } else {
 # reportmode is off, fix the permissions
 Write-Host "Setting permissions for" $homeFolder.Name -foregroundcolor white -backgroundcolor red
 # Add the user in format DOMAINUsername
 $username = $domainName + "" + $homeFolder.Name
 # Grant the user full control
 $accessLevel = "FullControl"
 # Should permissions be inherited from above?
 $inheritanceFlags = "ContainerInherit, ObjectInherit"
 # Should permissions propagate to below?
 $propagationFlags = "None"
 # Is this an Allow/Deny entry?
 $accessControlType = "Allow"
 try {
 # Create the Access Rule
 $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($username,$accessLevel,$inheritanceFlags,$propagationFlags,$accessControlType)

 # Attempt to apply the access rule to the ACL
 $Acl.SetAccessRule($accessRule)
 Set-Acl $homeFolder $Acl
 # if it hasn't errored out by now, increment the counter
 $fixedPermissions += 1
 } catch {
 # It failed!
 # Increment the fail count
 $unfixablePermissions += 1
 # and add the folder to the list of failed folders
 $failedFolders += $homeFolder
 }
 } #/if
 } #/if
} #/foreach

# Print out a summary

Write-Host ""
Write-Host $goodPermissions "valid permissions"
Write-Host $badPermissions "permissions needing repair"
if ($reportMode -eq $false) {Write-Host $fixedPermissions "permissions fixed"}
if ($unfixablePermissions -gt 0) {
 Write-Host $unfixablePermissions "ACLs could not be repaired."
 foreach ($folder in $failedFolders) {Write-Host " -" $folder}
}

# Cleanup
popd

Mandatory Profiles

GiraffeIT.com have been asked many a time to create mandatory ( or roaming as they used to be known ) profiles for various people.

The benefits are small, rapidly loading profiles that end users cannot write back to.

1.) Make a local user on the server

2.) Make the user member of the local administrators group on your server

3.) Login in with this user and customize for example the start menu

4.) Create a share on your file server.

5.) Copy the complete template folder from the C:Users directory to the new server share

6.) Rename the template folder to mandatory.V2 The .v2 is significant as it tells windows seven its a man profile for it.

7.) Delete the Local and LocalLow folders from the AppData folder

8.) Open REGEDIT and load the NTUSER.DAT hive ( make sure HKEY_USERS is highlighted

9.) Right-click on the Mandatory profile and choose permissions

10.) Delete the template user and add the Authenticated Users (Full Control)

11.) Unload the NTUSER.DAT from your registry

12.) Rename the NTUSER.DAT to NTUSER.MAN

13.) change the relevant users profiles in ADUC or via Policy preferences.

 

Preparing your desktop delays

GiraffeIT have been investigating a curious issue where no matter what server load is the profile that is loading ( a mandatory windows seven on since you ask ) is taking an age to get “past” preparing your desktop.

We moved the profiles to different servers, we disabled DFS namespaces ( crucially note that DFS replication is strongly advised against being used ) monitored network traffic with wireshark.

The problem wasn’t obvious. There were no RSOP/GPResult errors. All looked fine.

Logons were taking 2m40 under low load and 15minutes(!) under heavy load.

We eventually diagnosed the fault as an errant file filter placed on filescreening. The curious desktop.ini was being screened on the fileserver. Once removed the thin ( 1.7Mb ) mandatory profile loaded quickly.

23seconds now from CTRL-ALT-DEL to working desktop.

Deploystudio

GiraffeIT have found a fantastic bit of free Apple image software that really helps us deploy multiple Apple mac images to multiple machines. Its called Deploystudio ( available here )

Its straightforward to get it installed, and works really really well. Had a few minor snags ( mostly to do with clients errant DNS servers ) but no showstoppers.

Recommended !

 

 

NetVol not replicating, yet GPOs are ?

We were called out today for a job where a Domain controller ( DC ) was responding to requests , but only really, really slowly. Hit an alternative DC and it logged you on at the speed of light. Some digging was involved and GiraffeIT diagnosed that the netvol wasnt replicating.

The fix wasnt too bad.

  1. Stop the NTFRS service
  2. add in an administrator / elevated privledge user to the system information folder on the server with full control
  3. goto the folder that has a uniqueID and rename it ( I chose folderXYZold
  4. find the “private” folder , rename that ( I chose PrivateOLD )
  5. Restart the NTFRS service.
  6. Either await replication on cycle, or force start with the active directory sites and services snap in.

SOPA / Protect IP

We dont normally venture into the politics side of things here at GiraffeIT.com ,however this one has us a little bit worried.

If you are unsure of what the fuss about SOPA / ProtectIP is about , have a look at this :

SOPA / ProtectIP
[FMP]http://giraffeit.com/protectip/SOPA.mp4[/FMP]

 

 

DNS Scavenging

Happy new year !

A site I visited over the Christmas period was experiencing issues with DNS. There were no obvious faults other than an exceedingly large number of records in a somewhat small environment.

I discovered that the DHCP lease time was set to 8 hours and that scavenging was not set at all.

A few days later after the cycle had completed and 875 scavenged nodes later all is healthy again. Not to mention a decrease in network traffic.

Printer Scripts for Windows Seven

I have been onto a site recently, and had issues with the Group Policy Preferences not applying to the printers. I found out that this was due to the time it takes the printer to respond to the request to be “mapped” and made default.

I spent a few hours and hacked around some code and came up with this little masterpiece to allow multiple room printers to be added to the relevant OU based PC

‘—————Delete all Printers————————————————–
Dim wshNetwork, sPrintPath, clPrinters, i
Set wshNetwork = CreateObject(“WScript.Network”)

‘Remove Existing Printers
Set clPrinters = wshNetwork.EnumPrinterConnections
On Error Resume Next
For i = 0 to clPrinters.Count – 1 Step 2
wshNetwork.RemovePrinterConnection clPrinters.Item(i+1), true
Next
On Error Goto 0

‘—- For citrix script, un-comment following two lines:

‘Set Sh = CreateObject(“WScript.Shell”)
‘sys = Sh.ExpandEnvironmentStrings(“%CLIENTNAME%”) ‘sys= the returned workstation name (Citrix only)

‘—- For normal Windows machines un-comment the following line

sys = wshNetwork.ComputerName ‘sys = computer name (standard domain workstations – not citrix)

‘—- Note, you can’t have both of these uncommented!!!

‘User = CreateObject(“WScript.Network”).Username ‘ This returns the logged on username to variable: User

‘—————————————————————————————————————

CName = UCase(sys) ‘Get name from network object (Uppercase)
Set oNet = CreateObject(“WScript.Network”)

‘ -=( Add printer and set a default based on computer name (CName) )=-

‘ Test for Left(CName,NumberofChars)

‘ WEST BLOCK SCRIPTS

if Left(CName,3) = “W21” Then

oNet.AddWindowsPrinterConnection “\print-serverw21-mono”
oNet.AddWindowsPrinterConnection “\print-serverw21-colour”
oNet.SetDefaultPrinter “\print-serverw21-mono”

Elseif Left(CName,3) = “W22” Then

oNet.AddWindowsPrinterConnection “\print-serverw22-Mono”
oNet.AddWindowsPrinterConnection “\print-serverw22-Colour”
oNet.SetDefaultPrinter “\print-serverw22-mono”

etc etc

end IF

iOS5

Updated a few of my iDevices tonight. No real revolution , just a miriad of evolutions.

DelProf2

GiraffeIT.com was called into a site to help diagnose some GPO not working quite how they were expecting.
Long of the short is a locally cached copy of the profile was being stored on the local machines. There are a few settings you can use in Windows 2008R2 to prevent the cached copy staying on the machine for more than x days. However for completeness I wanted the profiles gone there and then. Cue DelProf2. ( available here ) A few tweaks and a rough and ready batch file called via a startup trigger in a GPO and voila. No more cached local profiles at machine turn on.

New Blog !

We hope to add more of GiraffeIT real world experiences in here. I hope to share some of the issues and solutions that the herd have met and overcome.

GiraffeIT – sticking our neck out so you dont have to