WSUS6.x Cannot open database “SUSDB” requested by the login. The login failed.~~Login failed for user ‘NT AUTHORITY\NETWORK SERVICE’

Are you receiving

Cannot open database “SUSDB” requested by the login. The login failed.~~Login failed for user ‘NT AUTHORITY\NETWORK SERVICE’ ?

 

Easy fix : Remove KB3159706

More complicated fix : https://support.microsoft.com/en-us/help/3159706/update-enables-esd-decryption-provision-in-wsus-in-windows-server-2012-and-windows-server-2012-r2

Powershell : Adding a GUI for a silent installer.

Seems counter intuative , right ?

Customer needs a pop up to display that software is being installed and offer the delay action. CM2012 could be used but it needs to be clear and simple for the (ab)users.

This happens to be for a SAP silent install , but the theory will work for all / any program.

 

###################################################################################################################################################################################################
# Coded By: Mr X
# Butchered by Bond
# Generated On: 07/12/2016 22:39.
# Version 1.3.2
# PreReq The required files need to copied to
# C:\$Batch$\Appscache\SAP7.40 including background image and .ico
###################################################################################################################################################################################################

#Small Functions
#Forms
#Function trigger calls
# Import the Assemblies for forms and drawings
[reflection.assembly]::loadwithpartialname(“System.Windows.Forms”) | Out-Null
[reflection.assembly]::loadwithpartialname(“System.Drawing”) | Out-Null

$objform = New-Object System.Windows.Forms.Form
$lblUpdates = New-Object System.Windows.Forms.Label
$lblUpdates1 = New-Object System.Windows.Forms.Label
$lblUpdates2 = New-Object System.Windows.Forms.Label
$okButton = New-Object System.Windows.Forms.Button
$DelayButton = New-Object System.Windows.Forms.Button
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#$a = 3 #number of delays allowed
#$DelayCount = 1 #initialise DelayCount
#$endprog = 0
function TimeDetection
{
$Time=Get-Date
$Time.AddHours(1).ToString(“HH:mm:ss”)
}
#not used
function GenratePopUp
{
[System.Windows.Forms.MessageBox]::Show(“You cannot delay installation further” , “SAP Installation continuing”)
}
#add reg key to run the script again if people power off / quit the installer

#Add into the registry
function AddRunOnce()
{
$BatchFix=’$’+’batch$’
Write-Host “Adding RunOnce script.” -foregroundcolor “magenta”
$RunOnceKey = “HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce”
#set-itemproperty $RunOnceKey “NextRun” (‘C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe -executionPolicy Unrestricted -File ‘ + “C:\$BatchFix\appscache\SAP7.40\.SAPInstaller.ps1”)
set-itemproperty $RunOnceKey “NextRun” (“C:\$BatchFix\appscache\EU_SAP_7.40_Extracted\setup\NWSAPSETUP.exe -ArgumentList /UPDATE /silent”)

}

#removes runone from the registry
function RemoveRunOnce()
{
#removes reg key to run the script again if people power off / quit the installer
Write-Host “Remvoing RunOnce script.” -foregroundcolor “magenta”
$RunOnceKey = “HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce”
remove-itemproperty $RunOnceKey “NextRun”
}

#Preps the installer , terminates the saplgpad ( only works in 7.20 , then runs the installer )
function InstallSap()
{
stop-process -name saplgpad -Force -ErrorAction SilentlyContinue
Start-Process ‘C:\$Batch$\appscache\EU_SAP_7.40_Extracted\setup\NWSAPSETUP.exe’ -ArgumentList “/UPDATE /silent”
RemoveScheduledTask
RemoveRunOnce
}

#does what the function name says ..
function AddScheduledTask
{
$BatchFix=’$’+’batch$’
$Time=Get-Date
$Start=$Time.ToString(“HH:mm:ss”)
$Delay=$Time.AddHours(1).ToString(“HH:mm:ss”)
$EndTime=$Time.AddHours(6).ToString(“HH:mm:ss”)
SchTasks /Create /SC DAILY /TN “SAP Powershell Task” /TR “powershell.exe -windowstyle hidden -file C:\$batchfix\appscache\SAP7.40\SAPGUIFinal.ps1 -ExecutionPolicy unrestricted” /ST $Start /ET $EndTime /RI 60
}

#guess ..
Function RemoveScheduledTask
{
#remove the schedule task
SchTasks /Delete /TN “SAP Powershell Task” /F
}

#Popup gnerator for informing users
function AndTheyAreOff
{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup(“Installation underway. Please do not use SAP for 30Minutes”,0,”SAP Installation”,0x0)
}

# test function for the loop listed lower down. Not actually in use
function IExplore()
{
Start-Process iexplore.exe
exit
}

# test function for the loop listed lower down. Not actually in use
function SomethingElse()
{
Start-Process calc.exe
exit
}

#Couple of variables I needed , no functions as stored and called elsewhere.
$BatchFix=’$’+’batch$’
$Time=Get-Date
$Start=$Time.ToString(“HH:mm:ss”)
$Delay=$Time.AddHours(1).ToString(“HH:mm:ss”)
$EndTime=$Time.AddHours(6).ToString(“HH:mm:ss”)

#Scheduled task installer check loop. There are no native PS commandlets in the kellogg deployed PS version so had to workaround
Function CheckIfTaskExists() {
$schedule = new-object -com Schedule.Service
$schedule.connect()
$tasks = $schedule.getfolder(“\”).gettasks(0)

foreach ($task in ($tasks | select Name)) {
echo “TASK : $($task.name)”
if($task.name.equals( “SAP Powershell Task”)) {
write-output “$($task.name) already exists”
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup(“You have delayed once , you cannot delay again. Press OK to continue”,0,”SAP Installation”,0x0)
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup(“SAP Now installing, please leave 30 minutes before using again”,0,”SAP Installation”,0x0)
InstallSap
return
}
}
SchTasks /Create /SC DAILY /TN “SAP Powershell Task” /TR “powershell.exe -windowstyle hidden -file C:\$batchfix\appscache\SAP7.40\SAPGUIFinal.ps1 -ExecutionPolicy unrestricted” /ST $Start /ET $EndTime /RI 60
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup(“Delaying for 1h. The installer will automatically pop up in 1h”,0,”SAP Installation”,0x0)
$objform.Close()
return
}

#FORM below.

#GenerateForm
function GenerateForm {
#
$killprog=$endprog
$DelCount=$DelayCount
$b=$a
$OnLoadForm_StateCorrection=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$objform.WindowState = $InitialFormWindowState
}
$objform.AutoSize = $True
$objform.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,255)
#ICON file specification
$Icon = New-Object system.drawing.icon (‘C:\$Batch$\Appscache\EU_SAP_7.40_Extracted\favicon.ICO’)
$objform.Icon = $Icon
#Background Image specified. Location C:\$Batch$\Appscache\EUSAPUpdates\Back1.bmp
$objform.BackgroundImage = [System.Drawing.Image]::FromFile(‘C:\$Batch$\Appscache\EU_SAP_7.40_Extracted\Background.png’)
$objform.BackgroundImageLayout = 2
$System_Drawing_Size = New-Object System.Drawing.Size
#Window Size Specified
$System_Drawing_Size.Height = 600
$System_Drawing_Size.Width = 1000
$objform.ClientSize = $System_Drawing_Size
$objform.Font = New-Object System.Drawing.Font(“Microsoft Sans Serif”,8.25,1,3,0)
$objform.FormBorderStyle = 5
$objform.Name = “objform”
$objform.Text = “EU SAP GUI 7.40 Upgrade”

#START Specify Attributes of Top Line Window text
$lblUpdates.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,255)
$lblUpdates.DataBindings.DefaultDataSourceUpdateMode = 0
$lblUpdates.FlatStyle = 1
$lblUpdates.Font = New-Object System.Drawing.Font(“Microsoft Sans Serif”,15,1,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 155
$System_Drawing_Point.Y = 160
$lblUpdates.Location = $System_Drawing_Point
$lblUpdates.Name = “lblUpdates”
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 50
$System_Drawing_Size.Width = 650
$lblUpdates.Size = $System_Drawing_Size
$lblUpdates.TabIndex = 3
$lblUpdates.Text = “Mandatory upgrade to SAP and Business Explorer Applications.”
$lblUpdates.TextAlign = 2
#END Specify Attributes of Line 3 Box text
#Print Top Line of Box text
$objform.Controls.Add($lblUpdates)
#START Specify Attributes of Middle Line Window text
$lblUpdates1.DataBindings.DefaultDataSourceUpdateMode = 0
$lblUpdates1.Font = New-Object System.Drawing.Font(“Microsoft Sans Serif”,16,5,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 155
$System_Drawing_Point.Y = 225
$lblUpdates1.Location = $System_Drawing_Point
$lblUpdates1.Name = “lblUpdates1”
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 50
$System_Drawing_Size.Width = 650
$lblUpdates1.Size = $System_Drawing_Size
$lblUpdates1.TabIndex = 5
$lblUpdates1.Text = “Please save and close all your work before continuing”
$lblUpdates1.TextAlign = 2
#END Specify Attributes of Middle Line Window text
#Print Middle Line of Window Text
$objform.Controls.Add($lblUpdates1)
#START Specify Attributes of Bottom Line Window text
$lblUpdates2.DataBindings.DefaultDataSourceUpdateMode = 0
$lblUpdates2.Font = New-Object System.Drawing.Font(“Microsoft Sans Serif”,15,1,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 155
$System_Drawing_Point.Y = 290
$lblUpdates2.Location = $System_Drawing_Point
$lblUpdates2.Name = “lblUpdates2”
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 50
$System_Drawing_Size.Width = 650
$lblUpdates2.Size = $System_Drawing_Size
$lblUpdates2.TabIndex = 6
$lblUpdates2.Text = “Please click on OK button to continue”
$lblUpdates2.TextAlign = 2
#END Specify Attributes of Bottom Line Window text
#Print Boittom Line of Window text
$objform.Controls.Add($lblUpdates2)
#START Specify Attributes of Dev Button
$okButton.BackColor = [System.Drawing.Color]::FromArgb(255,220,220,220)
$okButton.DataBindings.DefaultDataSourceUpdateMode = 0
$okButton.FlatAppearance.BorderColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$okButton.FlatAppearance.BorderSize = 10
$okButton.FlatAppearance.MouseDownBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$okButton.FlatAppearance.MouseOverBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$okButton.FlatStyle = 3
$okButton.Font = New-Object System.Drawing.Font(“Microsoft Sans Serif”,15,1,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 300
$System_Drawing_Point.Y = 390
$okButton.Location = $System_Drawing_Point
$okButton.Name = “okButton”
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 90
$System_Drawing_Size.Width = 175
$okButton.Size = $System_Drawing_Size
$okButton.TabIndex = 1
$okButton.Text = “OK – Continue”
#On Click of OK Button Close SAP
$okButton.add_Click(
{
$objform.Close()
AndTheyAreOff
InstallSap
RemoveRunOnce
}
)
$objform.Controls.Add($okButton)
#END Specify Attributes of OK Button and Publish button
#START Specify Attributes of Delay Button
$DelayButton.BackColor = [System.Drawing.Color]::FromArgb(255,220,220,220)
$DelayButton.FlatAppearance.BorderColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$DelayButton.DataBindings.DefaultDataSourceUpdateMode = 0
$DelayButton.FlatAppearance.BorderSize = 10
$DelayButton.FlatAppearance.MouseDownBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$DelayButton.FlatAppearance.MouseOverBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$DelayButton.FlatStyle = 3
$DelayButton.Font = New-Object System.Drawing.Font(“Microsoft Sans Serif”,15,1,3,0)
$DelayButton.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 480
$System_Drawing_Point.Y = 390
$DelayButton.Location = $System_Drawing_Point
$DelayButton.Name = “DelayButton”
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 90
$System_Drawing_Size.Width = 175
$DelayButton.Size = $System_Drawing_Size
$DelayButton.TabIndex = 0
$DelayButton.Text = “Delay for 1Hour”
#On Click of Dev Button call CopyIni
$DelayButton.add_Click(
{
$objform.Close()
CheckIfTaskExists
#Exit

}
)

$objform.Controls.Add($DelayButton)
#END Specify Attributes of Standard Button and Publish button

#Save the initial state of the form
$InitialFormWindowState = $objform.WindowState

#Init the OnLoad event to correct the initial state of the form
$objform.add_Load($OnLoadForm_StateCorrection)

#Show the Form
$objForm.FormBorderStyle = ‘Fixed3D’
$objForm.MaximizeBox = $false
$objForm.Visible = $false
$objform.ShowDialog()| Out-Null

$DelayCount = $DelCount
$a=$b
$endprog = $killprog
}

#END.Function GenerateForm

AddRunOnce
GenerateForm

Moving Windows 2008r2 Cluster Shares without DFS

You can move Windows 2008r2 cluster shares without the need for DFS.

It goes a little something like this

Data copy

I used emcopy to move all data from the existing sahre to the newly added share as it copies all and sundry. Quickly. Ill not go through these steps.

 

Adding Disk to services

Add in a new cluster disk , assign it to a new file server service that belongs to the existing file server role. Bring it all online , allocating a drive letter as you see fit

Add a file share to the existing shared disk. Give it a unique name ( you will see why later )

Add a file share to the newly added disk, again give it a new unique name.

 

 

Identifying Shares

Open regedit.

Search for the unique name on the existing share. Go slightly higher up the registry tree. Note parameters subkey. Note above that there is a long , long key. Copy that long identifier into notepad. Mark it something like existing share and finally paste in the long value

Repeat for the new share.

Save the notepad file just in case.

 

Moving Shares

Go back to regedit

Export the existing registry key from the long name. Name its something like ITS ALL GONE WRONG I NEED TO GET TO A SAFE PLACE.reg

Copy the reg file and paste it. Therefore duplicating it. Rename it Migration

Open/Edit it in notepad.

Replace every instance of the existing long key with the newly added key ( for the new drive ) you identified earlier. You are effectively here spoofing the old disk name with the new disk name

Replace every instance of the existing drive letter with the new shared disk. Save the newly tampered with reg file.

Take a brave pill now.

Drop all the share with the Manager shares and storage. You will be warned about dropping admin shares. Dont drop those.

Import the reg file you tampered with earlier.

Offline both Disk drives

Offline both file servers

Bring the Disk Drives back on

Bring the File server back on.

Hope and wait.

You should now have all the shares on the newly added drive. All the shares will have been dropped on the existing drive that we can assume will be retired

 

You *must* restart the cluster services on the passive node to refresh the passive nodes registry.

 

That should be it. I eyeballed the Shared Folder #client connections.

 

If you really , really want to use the old drive letter that was in existence, and I havent tested this : drop the now disused cluster disk from the failover cluster manager , re add a new RDM or independent persistent eager zero’d disk and allocate it the desired drive letter.

Do the same migration process detailed above.

 

 

 

 

 

SCCM Log files.

Ever wondered what the myriad of log files do ? Wonder no more !

https://technet.microsoft.com/en-gb/library/hh427342.aspx

Here is a great breakdown of the above information :

https://blogs.msdn.microsoft.com/lxchen/2009/04/03/a-list-of-sccm-log-files/

 

 

Powershell : Remove logon scripts

Removes logon scripts on a particular OU.

$path = [adsi]”LDAP://OU=Users,OU=IT,OU=Eu,DC=eu,DC=somewhere,DC=com”
$obj = New-Object adsisearcher($path , “(scriptPath=*)”)
$users = $obj.FindAll()

foreach ($user in $users)
{
$user = [adsi]$user.path
$user.PutEx(1,”scriptPath”,$null)
$user.SetInfo()
}

Powershell stop and restart multiple KDC

Powershell stop and restart multiple KDC

We had a requirement to stop and restart the KDC on multiple remote DCs.

Rather than go around each one , we wrote a script .

 

function DateAndTimeLog
{
Get-date
}
function testIf
{
If (Test-Connection -comp $dc -count 1 -quiet) {
$dc+” is online! ”
}
Else {
$dc+” is offline, moving to next Domain Controller”
continue;
}

}
function SlowItDown
{
Start-Sleep -s 5
}

function MessageStop
{
Write-Host “stopping the KDC on $DC ”
Write-Output “stopping the KDC on $DC ”
}

function MessageStart
{
Write-Host “now restarting the KDC on $DC ”
Write-Output “now restarting the KDC on $DC ”
Write-Output “finished process”
Write-Output ” —————— ”
}

$File =”C:DCResults.txt”
$DCsinOurDomain= Get-ADDomainController -Filter *

ForEach($DC in $DCsinOurDomain.HostName){
DateAndTimeLog | Out-File $File -Append
testif | ft | Out-File $File -Append
(Get-WmiObject Win32_Service -filter “name=’kdc'” -ComputerName $DC).StopService()
MessageStop | Out-File $File -Append
SlowItDown
(Get-WmiObject Win32_Service -filter “name=’kdc'” -ComputerName $DC).StartService()
MessageStart | Out-File $File -Append

}

Powershell : Find all active users who havent logged in

Request from a customer. Find me all active ( IE not disabled ) users in a particular OU who have never logged in.

“I have a powershell for that” appears to be the default answer for most queries these days …

Get-ADUser -Filter {enabled -eq $true} -SearchBase “OU=Eu,DC=eu,DC=notyou,DC=com” -Properties “LastLogonDate” | sort-object -property lastlogondate -descending |Format-Table -property Name, sAMAccountName, LastLogonDate -AutoSize >>c:temptestoutput.csv

Powershell : remote machines static dns to DHCP

This will read an input file , and using the WMI object change any statically assigned DNS to DHCP.

 

# grabs the ListofMachines from the CSV
$ListofMachines=Get-Content “c:tempmachines.csv”
# loop starts here
foreach ($machine in $ListofMachines)
{
#Performs a release ( if needed ! use with care remotely ! )
#Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $machine | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | ForEach-Object -Process {$_.ReleaseDHCPLease()}
# query the $machine that has the DHCP enabled adapter and performs the renewal
$wmi = Get-WmiObject win32_networkadapterconfiguration -computerName $machine -filter “ipenabled =’true'”;
$wmi.EnableDHCP();
$wmi.SetDNSServerSearchOrder();

Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $machine | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | ForEach-Object -Process {ipconfig /flushdns}

}

Powershell : renew multiple machines DHCP scopes

# grabs the ListofMachines from the CSV
$ListofMachines=Get-Content “c:tempmachines.csv”
# loop starts here
foreach ($machine in $ListofMachines)
{
#Performs a release ( if needed ! use with care remotely ! )
#Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $machine | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | ForEach-Object -Process {$_.ReleaseDHCPLease()}
# query the $machine that has the DHCP enabled adapter and performs the renewal
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $machine | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | ForEach-Object -Process {$_.RenewDHCPLease()}
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName 10.130.54.53 | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | ForEach-Object -Process {ipconfig /flushdns}
#log for Output!
write-output “$machine has had IP renewed ” |out-file -filepath “c:tempresultsofDHCPLease04032015.csv” -append
}

Powershell : renew remote IP address

We wrote this at GiraffeIT.com. If you know the remote IP or DNS name of a machine it will help you renew a DHCP lease and flush the DNS.

Very useful if you have a remote machine with a scope change and its not being reflected.

 

write-host “—————————–”
write-host “DHCP lease renewal + flushDNS”
write-host “—————————–”
$machine = read-host “IP/Name of machine needing lease renewal ? ”
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $machine | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | ForEach-Object -Process {$_.RenewDHCPLease()}
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $machine | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | ForEach-Object -Process {ipconfig /flushdns}

Powershell – logon script based on username

Devised this script that will run a program based on the username of the logged in user and resizes the window as needed.

 

#find the currently logged on user and stick the name into the $LoggedOnUser variable
$LoggedOnUser=(Get-WmiObject -Class Win32_Process | Where-Object {$_.ProcessName -eq ‘explorer.exe’}).GetOwner() | select User
echo $LoggedOnUser

#Uncomment the line below and add into line 2 place if using on a local machine
#$LoggedOnUser=Get-WMIObject -class Win32_ComputerSystem | select username
#if statement now checking who is who.

If ($LoggedOnUser.user -eq “abc1”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc2”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc3”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc4”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc5”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc6”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc7”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc8”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc9”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc10”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc11”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc12”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc13”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc14”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc15”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc16”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc17”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abc18”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}
elseif ($LoggedOnUser.user -eq “abcz19”)
{
& “C:Windowstrace32.exe”
& “C:Windowsregedit.exe”
}

#final error trap : no username recognised ? Give them a popup box
else
{
[System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
[Windows.Forms.MessageBox]::Show(“This account has not been assigned a citrix autorun. Now logging off ”, “Citrix Presentation”, [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Information)
}

#makes sure the programs are open by delaying the script by 15 seconds
start-sleep -s 15
#find process now and move it
Add-Type @”
using System;
using System.Runtime.InteropServices;

public class Win32 {
[DllImport(“user32.dll”)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
}
“@
[int]$X = 960
[int]$Y = 0
[int]$nWidth = 960
[int]$nHeight =1080
[string]$processName = “proficyclient”

$handle = (Get-Process | where {$_.ProcessName -eq $processName}).MainWindowHandle

[Win32]::MoveWindow($handle, $X, $Y, $nWidth, $nHeight, $true )

#find second process
Add-Type @”
using System;
using System.Runtime.InteropServices;

public class Win32 {
[DllImport(“user32.dll”)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
}
“@
[int]$X = 0
[int]$Y = 0
[int]$nWidth = 960
[int]$nHeight =1080
[string]$processName = “vlc”

$handle = (Get-Process | where {$_.ProcessName -eq $processName}).MainWindowHandle

[Win32]::MoveWindow($handle, $X, $Y, $nWidth, $nHeight, $true )

$a = new-object -comobject wscript.shell
$b = $a.popup(“Please wait 15 seconds. This window will dissapear after 15 seconds “,15,”Wait”)

Powershell : export-dhcpserver

Export/Import existing scopes

 

Export the DHCP scope ( whilst leaving active on source ) from SERVER using either powershell or netsh

 

Powershell commands:

 

Export-DhcpServer [-File] <String> [-CimSession <CimSession> ] [-ComputerName <String> ] [-Force] [-Leases] [-Prefix <IPAddress[]> ] [-ScopeId <IPAddress[]> ] [ <CommonParameters>]

 

Example: export-dhcpserver -ComputerName SERVER -file “C:PATHNAME.XML”
Pre-Requisites for the PowerShell at that it is run on a windows 2012 server. The PowerShell will export it as an  XML file

 

To import the scope ( note that using the import-dhcpserver it DOES NOT overwrite any existing scopes )

 

Import-DhcpServer -file “C:PATHFILE.XML” -BackupPath “C:PATH”

 

 

NetSh verison :

 

This needs to be run on the server that holds the current DHCP scope that is being exported

 

Netsh export c:tempdhcpdb all

 

I prefer using PowerShell as I have tried and tested it. However it wont work with Windows 2003 servers

 

To import

Copy the .txt file that was created earlier and

 

netsh dhcp server import c:tempdhcp.txt all

 

Again this will NOT overwrite existing scopes. Refresh the window if it doesn’t appear.

Powershell: backup all DHCP servers

This script MUST be run on a 2012 server

#you define some share ( eg \server1dhcpbackup$  , and DNS suffix eg my.domain.com

#remove any variables that might have been stored, otherwise it has a bit of a wobble.
Remove-Variable dhcpServer
Remove-Variable dhcpServers

#we are going to do a check first for all files/folders that are older than X days ( you specify in the code )
# set folder path
$folderloc = “\somesharedhcpbackups$”

# set min age of files
$max_days = “70”

# get the current date
$curr_date = Get-Date

# determine how far back we go based on current date
$del_date = $curr_date.AddDays($max_days)

# delete the files
Get-ChildItem $folderloc -Recurse | Where-Object { $_.LastWriteTime -lt $del_date } | Remove-Item -Recurse -Confirm:$False

#this bit finds all the servers ( in the DC !) and only returns the chosen suffx ones as there are ones in the US
$dhcpServers= Get-DhcpServerInDC | where-object {$_.dnsname –match “dns suffix”}

#going to prepare a timestamp system now. l33t style.
$CurrentDate = Get-Date
$CurrentDate = $CurrentDate.ToString(‘dd-MM-yyyy_hh-mm-ss’)

#this bit loops and does the dhcp backup. Backs up the files locally to the path you can see, then copys the file to the $severloc ( which is in
#essence just the dhcpservers dns name )
foreach($dhcpServer in $dhcpServers){
$serverloc = $dhcpServer.DnsName
$from = “\$serverlocc$DHCPBackups”
backup-dhcpserver -ComputerName $dhcpserver.DnsName -Path “c:DHCPBackups”
Copy-Item $from \somesharedhcpbackups$$CurrentDate$serverloc -Recurse }

 

 

 

 

 

 

Powershell : Ping all machines

In theory you should know if all your machines are active or not in your environment. However as the environment gets bigger or more people work on it this can become confusing.

This powershell script reads a list ( in txt format ) of machines you want to ping , how many pings , max concurrent pings times to ping and gives you an output file. We cant claim any glory on the the script but we are sharing the knowledge

 

Param(
[parameter(Mandatory=$true)]
$InputFilePath,
[parameter(Mandatory=$true)]
$MaxConcurrent,
[parameter(Mandatory=$true)]
$TimesToPing,
$TimeoutInSeconds,
$ResolveNames
)

$Start = [System.DateTime]::Now
Write-Host “Version 1.0”
Write-Host “InputFilePath:”$InputFilePath
Write-Host “MaxConcurrent:”$MaxConcurrent
Write-Host “TimesToPing:”$TimesToPing
Write-Host “TimeoutInSeconds:”$TimeoutInSeconds
Write-Host “ResolveNames:”$ResolveNames

function GetNamesFromTextFile
{
param($file)

$ht = @{}

try
{
foreach ($line in [System.IO.File]::ReadLines($file))
{
try { $ht.Add($line.ToString().Trim(), $line.ToString().Trim()) } catch {}
}
}
catch
{
Write-Host “Failed to Read File, Exiting:”$ms -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Yellow
exit
}

return $ht
}

function GetStatusCodeString
{
param ($code)

switch ($code)
{
$null {$ret = “Ping Command Failed”}
0 {$ret = “Success”}
11001 {$ret = “Buffer Too Small”}
11002 {$ret = “Destination Net Unreachable”}
11003 {$ret = “Destination Host Unreachable”}
11004 {$ret = “Destination Protocol Unreachable”}
11005 {$ret = “Destination Port Unreachable”}
11006 {$ret = “No Resources”}
11007 {$ret = “Bad Option”}
11008 {$ret = “Hardware Error”}
11009 {$ret = “Packet Too Big”}
11010 {$ret = “Request Timed Out”}
11011 {$ret = “Bad Request”}
11012 {$ret = “Bad Route”}
11013 {$ret = “TimeToLive Expired Transit”}
11014 {$ret = “TimeToLive Expired Reassembly”}
11015 {$ret = “Parameter Problem”}
11016 {$ret = “Source Quench”}
11017 {$ret = “Option Too Big”}
11018 {$ret = “Bad Destination”}
11032 {$ret = “Negotiating IPSEC”}
11050 {$ret = “General Error”}
default {$ret = “Ping Failed”}
}

return $ret
}

function GetPingResultsFromHashTable
{
param($ht, $maxConcurrent, $count, $timeout)

$bDone = $false
$i = 0
$totalMachines = 0
$htResults = @{}
$dotTime = [System.DateTime]::Now
if ($timeout -eq $null) {$timeout = 120}

Write-Host (“Sending Ping Command to {0} Machines” -f $ht.Count) -NoNewline

foreach ($name in $ht.GetEnumerator())
{
while ((Get-Job -State Running).Count -ge $maxConcurrent)
{
Start-Sleep -Seconds 1
if ($i -ge 50) { Write-Host “*”; $i = 0 }
else { Write-Host “*” -NoNewline; $i++ }
}

$job = Test-Connection -ComputerName $name.Key.ToString() -Count $count -AsJob
$job.name = “ping:{0}” -f $name.Key.ToString()

if ([System.DateTime]::Now -gt $dotTime)
{
$dotTime = ([System.DateTime]::Now).AddSeconds(1)
if ($i -ge 50) { Write-Host “.”; $i = 0 }
else { Write-Host “.” -NoNewline; $i++ }
}
}

#Start time now, exit in case of timeout
$timeout = ([System.DateTime]::Now).AddSeconds($timeout)
$dotTime = [System.DateTime]::Now
$i = 0
Write-Host
Write-Host “Getting Ping Results” -NoNewline

while(!($bDone))
{
$results = Get-Job -Name ‘ping:*’
$bRunning = $false

foreach ($result in $results)
{
if ($result.State -ne ‘Running’)
{
if ($result.State -eq ‘Failed’)
{
#resubmit job
if ($i -ge 50) { Write-Host “+”; $i = 0 }
else { Write-Host “+” -NoNewline; $i++ }
$job = Test-Connection -ComputerName $result.Name.ToString().Split(“:”)[1] -Count $count -AsJob
$job.name = “ping:{0}” -f $result.Name.ToString().Split(“:”)[1]
}
else
{
try { $htResults.Add($result.Name.ToString().Split(“:”)[1], (Receive-Job $result)) } catch {}
$totalMachines++
}

if ([System.DateTime]::Now -gt $dotTime)
{
$dotTime = ([System.DateTime]::Now).AddSeconds(1)
if ($i -ge 50) { Write-Host “.”; $i = 0 }
else { Write-Host “.” -NoNewline; $i++ }
}

try { Remove-Job $result } catch {}
}
else
{
$bRunning = $true
}
}

#Check for timeout condition, clean up all jobs if true
if ([System.DateTime]::Now -gt $timeout)
{
$bDone = $true
Write-Host “Timeout reached, removing jobs”
$results = Get-Job -Name ‘ping:*’
foreach ($result in $results)
{
Write-Host “RemoveJob:”$result.Name
try
{
Stop-Job $result
try { Remove-Job $result -Force } catch {}
}
catch {}
}
}

#If the timeout hasn’t been reached and jobs are still running, loop again
if (!($bRunning)) { $bDone = $true }
}

Write-Host
Write-Host (“Received Ping Results From {0} Machines” -f $totalMachines)

return $htResults
}

function ResolveNamesFromPingResults
{
param($array, $maxConcurrent, $resolveNames, $timeout)

try { if ($resolveNames -ne $null) { [bool]$resolveNames = [System.Convert]::ToBoolean($resolveNames) } } catch {}

$htResults = @{}

if ($resolveNames)
{
$dotTime = ([System.DateTime]::Now)
if ($timeout -eq $null) {$timeout = 120}
$i = 0
$scriptBlock =
{
param($s)
try { $ret = [System.Net.DNS]::GetHostEntry($s) } catch {}
return $ret
}
Write-Host (“Resolving DNS Names for {0} Machines” -f $array.Count) -NoNewline
foreach ($name in $array)
{
while ((Get-Job -State Running).Count -ge $maxConcurrent)
{
Start-Sleep -Seconds 1
if ($i -ge 50) { Write-Host “*”; $i = 0 }
else { Write-Host “*” -NoNewline; $i++ }
}
$job = Start-Job -ScriptBlock $scriptBlock -ArgumentList $name.NameInList
$job.name = “resolve:{0}” -f $name.NameInList
if ([System.DateTime]::Now -gt $dotTime)
{
$dotTime = ([System.DateTime]::Now).AddSeconds(1)
if ($i -ge 50) { Write-Host “.”; $i = 0 }
else { Write-Host “.” -NoNewline; $i++ }
}
}

#Start time now, exit in case of timeout
$timeout = ([System.DateTime]::Now).AddSeconds($timeout)
$dotTime = ([System.DateTime]::Now)
$i = 0
$bDone = $false

Write-Host
Write-Host “Getting DNS Results” -NoNewline
while(!($bDone))
{
$results = Get-Job -Name ‘resolve:*’
$bRunning = $false

foreach ($result in $results)
{
if ($result.State -ne ‘Running’)
{
if ($result.State -eq ‘Failed’)
{
#resubmit job
if ($i -ge 50) { Write-Host “+”; $i = 0 }
else { Write-Host “+” -NoNewline; $i++ }
$job = Start-Job -ScriptBlock $scriptBlock -ArgumentList $result.Name.ToString().Split(“:”)[1]
$job.name = “resolve:{0}” -f $result.Name.ToString().Split(“:”)[1]
}
else
{
try { $htResults.Add($result.Name.ToString().Split(“:”)[1], (Receive-Job $result)) } catch {continue}
}

if ([System.DateTime]::Now -gt $dotTime)
{
$dotTime = ([System.DateTime]::Now).AddSeconds(1)
if ($i -ge 50) { Write-Host “.”; $i = 0 }
else { Write-Host “.” -NoNewline; $i++ }
}

try { Remove-Job $result -Force} catch {}
}
else
{
$bRunning = $true
}
}

#Check for timeout condition, clean up all jobs if true
if ([System.DateTime]::Now -gt $timeout)
{
$bDone = $true
Write-Host “Timeout reached, removing jobs”
$results = Get-Job -Name ‘resolve:*’
foreach ($result in $results)
{
Write-Host “RemoveJob:”$result.Name
try
{
Stop-Job $result
try { Remove-Job $result -Force } catch {}
}
catch {}
}
}

#If the timeout hasn’t been reached and jobs are still running, loop again
if (!($bRunning)) { $bDone = $true }
}
Write-Host
Write-Host (“Received DNS Results From {0} Machines” -f $htResults.Count)
}

return $htResults
}

function GetFormattedPingResultsFromHashTable
{
param($ht)

$fResults = New-Object System.Collections.ArrayList
$dotTime = ([System.DateTime]::Now)
$i = 0
Write-Host “Formatting Ping Results” -NoNewLine

foreach ($result in $ht.GetEnumerator())
{
#There are multiple pings here if we ping more than once per computer
$originalAddress = $result.Key.ToString()
$pingCount = 0
$successCount = 0
$status = ‘Ping Job Failed’
$pingedFrom = ‘Ping Job Failed’
$successPercentage = 0

try { $pings = $result.Value.Count } catch { $pings = 0 }
if ($pings -gt 0)
{
$status = GetStatusCodeString -code $result.Value[$pings-1].StatusCode
$pingedFrom = $result.Value[$pings-1].PSComputerName
}

foreach ($ping in $result.Value)
{
$pingCount++
if ($ping.StatusCode -eq 0) { $successCount++ }
#If you try to get the IPv4Address or IPv6Address it slows down this loop significantly
}

#Calculate percentage
if ($pingCount -ne 0) { $successPercentage = ($successCount / $pingCount) * 100 }
else { $successPercentage = 0 }

#Add to array
$o = New-Object PSObject -Property @{
NameInList = $originalAddress
PingedFrom = $pingedFrom
SuccessPercentage = $successPercentage
LastPingStatus = $status
}

[void]$fResults.Add($o)

if ([System.DateTime]::Now -gt $dotTime)
{
$dotTime = ([System.DateTime]::Now).AddSeconds(1)
if ($i -ge 50) { Write-Host “.”; $i = 0 }
else { Write-Host “.” -NoNewline; $i++ }
}
}

Write-Host
Write-Host (“Formatted Ping Results for {0} Machines” -f $fResults.Count)

return $fResults
}

function GetFormattedPingAndDNSResults
{
param($pingResults, $dnsResults)

if ($dnsResults.Count -ne 0)
{
Write-Host “Formatting DNS Results” -NoNewLine
$dotTime = ([System.DateTime]::Now)
$i = 0
foreach ($ping in $pingResults)
{
$dns = $dnsResults.Get_Item($ping.NameInList)
if ($dns -ne $null)
{
$bFirst = $true
foreach ($ip in $dns.AddressList)
{
if ($bFirst){ $ipList = $ip }
else { $ipList += “|” + $ip }
}

$fqdn = $dns.HostName
}
else
{
$ipList = $null
$fqdn = ‘No DNS Entry Found’
}

$ping | Add-Member -MemberType NoteProperty -Name NameFromDNS -value $fqdn -Force
$ping | Add-Member -MemberType NoteProperty -Name IPAddressListFromDNS -value $ipList -Force

if ([System.DateTime]::Now -gt $dotTime)
{
$dotTime = ([System.DateTime]::Now).AddSeconds(1)
if ($i -ge 50) { Write-Host “.”; $i = 0 }
else { Write-Host “.” -NoNewline; $i++ }
}
}
Write-Host
Write-Host (“Formatted DNS Results for {0} Machines” -f $pingResults.Count)
}

return $pingResults
}

function GetOutputPath
{
param($fileName, $dir)
$outputPath = $dir + “” + $fileName
return $outputPath
}

function GetTimeSpanStringInMinutesAndSeconds
{
param($startTime, $endTime)

$time = $startTime.Subtract($endTime)
$minutes = $time.ToString().Split(“:”)[1]
$seconds = $time.ToString().Split(“:”)[2].Split(“.”)[0]
$timeSpan = “{0} Minutes and {1} Seconds” -f $minutes, $seconds
return $timeSpan
}

function GetSuccessPingCount
{
param($results)

$successCount = 0
foreach ($result in $results)
{
if ($result.SuccessPercentage -gt 0) { $successCount++ }
}

return $successCount
}

function GetDNSNamesResolvedCount
{
param($results)

$namesResolved = 0
foreach ($result in $results)
{
if ($result.IPAddressListFromDNS -ne $null) { $namesResolved++ }
}

return $namesResolved
}

function GetPercentageAsString
{
param($n1, $n2)

if ($n1 -ne 0) { $percentage = ($n1 / $n2) * 100 }
else { $percentage = 0 }

$percentage = (“{0:N0}” -f $percentage) + “%”

return $percentage
}

#Read in Names from text file
$Names = GetNamesFromTextFile -file $InputFilePath

#Get ping results in a hash table. The key is the name and the value is the returned array of ping objects (one element per ping).
$Results = GetPingResultsFromHashTable -ht $Names -maxConcurrent $MaxConcurrent -count $TimesToPing -timeout $TimeoutInSeconds

#Format ping results into an array of objects
$FormattedPingResults = GetFormattedPingResultsFromHashTable -ht $Results

#Resolve DNS Names if specified
$DNSResults = ResolveNamesFromPingResults -array $FormattedPingResults -maxConcurrent 5 -resolveNames $ResolveNames -timeout $TimeoutInSeconds

#Format DNS results by adding them to the ping results
$FormattedPingResults = GetFormattedPingAndDNSResults -pingResults $FormattedPingResults -dnsResults $DNSResults

#Output to CSV
$OutputPath = GetOutputPath -fileName ‘PingResults.csv’ -dir ([Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath)
try { if ($ResolveNames -ne $null) { [bool]$ResolveNames = [System.Convert]::ToBoolean($ResolveNames) } } catch {}
if ($ResolveNames) { $FormattedPingResults | Sort-Object SuccessPercentage | Select-Object NameInList, NameFromDNS, IPAddressListFromDNS, SuccessPercentage, LastPingStatus, PingedFrom | Export-Csv -Path $OutputPath -NoTypeInformation }
else { $FormattedPingResults | Sort-Object SuccessPercentage | Select-Object NameInList, SuccessPercentage, LastPingStatus, PingedFrom | Export-Csv -Path $OutputPath -NoTypeInformation }

#Output Statistics
$SuccessPingCount = GetSuccessPingCount -results $FormattedPingResults
Write-Host “—Statistics—” -ForegroundColor Green
Write-Host (“Total Time Elapsed: ” + (GetTimeSpanStringInMinutesAndSeconds -startTime $Start -endTime ([System.DateTime]::Now))) -ForegroundColor Green
Write-Host “Total Names Pinged:”$FormattedPingResults.Count -ForegroundColor Green
Write-Host (“Hosts that Responded: ” + ($SuccessPingCount)) -ForegroundColor Green
Write-Host (“DNS Names Resolved: ” + (GetDNSNamesResolvedCount -results $FormattedPingResults)) -ForegroundColor Green
Write-Host (“Percentage of Hosts that Responded at Least Once: ” + (GetPercentageAsString -n1 $SuccessPingCount -n2 $FormattedPingResults.Count)) -ForegroundColor Green
Write-Host “CSV Output Location:”$OutputPath -ForegroundColor Yellow

Powershell : Find all servers in a domain

This code will find all servers in a domain and return its canonical location

 

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.Filter = ‘(OperatingSystem=Window*Server*)’
“Name”,”canonicalname”,”distinguishedname” | Foreach-Object {$null = $objSearcher.PropertiesToLoad.Add($_) }
$objSearcher.FindAll() | Select-Object @{n=’Name’;e={$_.properties[‘name’]}},@{n=’ParentOU’;e={$_.properties[‘distinguishedname’] -replace ‘^[^,]+,’}} | ft -autosize

Powershell : add users from one group to another.

Simple script to add multipe users from one group to another easily.

 

Will show on screen error if they already are members of the destination group but carry on going on error.

 

 

======================================================================================

$Source_Group = “CN=MAC,OU=Test Groups,OU=Groups,OU=GB,,DC=whatever,DC=com”

$Destination_Group = “CN=newMAC,OU=Test Groups,OU=Groups,OU=GB,,DC=whatever,DC=com”

 

$Target = Get-ADGroupMember -Identity $Source_Group

foreach ($Person in $Target) {

Add-ADGroupMember -Identity $Destination_Group -Members $Person.distinguishedname

}

 

Powershell export virtual machines IP

This script is pretty handy, it will connect to the Virtual Center you specify in Powershell.

 

# you will need to adjust the viserver name
connect-viserver mecvm01.eu.kellogg.com

$reportedvms=New-Object System.Collections.ArrayList
$vms=get-view -viewtype virtualmachine |Sort-Object -Property { $_.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualEthernetCard]} | Measure-Object | select -ExpandProperty Count} -Descending

foreach($vm in $vms){
$reportedvm = New-Object PSObject
Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Guest -value $vm.Name
Add-Member -InputObject $reportedvm -MemberType noteProperty -name UUID -value $($vm.Config.Uuid)
$networkcards=$vm.guest.net | ?{$_.DeviceConfigId -ne -1}
$i=0
foreach($ntwkcard in $networkcards){
Add-Member -InputObject $reportedvm -MemberType NoteProperty -Name “networkcard${i}.Network” -Value $ntwkcard.Network
Add-Member -InputObject $reportedvm -MemberType NoteProperty -Name “networkcard${i}.MacAddress” -Value $ntwkcard.Macaddress
Add-Member -InputObject $reportedvm -MemberType NoteProperty -Name “networkcard${i}.IpAddress” -Value $($ntwkcard.IpAddress|?{$_ -like “*.*”})
Add-Member -InputObject $reportedvm -MemberType NoteProperty -Name “networkcard${i}.Device” -Value $(($vm.config.hardware.device|?{$_.key -eq $($ntwkcard.DeviceConfigId)}).gettype().name)
$i++
}
$reportedvms.add($reportedvm)|Out-Null
}

$reportedvms|Export-Csv c:myreport.csv

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