Friday 16 October 2009

Update Active Directory from WMI

The Need:
I needed to update the computer description field for servers in AD with the site information where the computer was located. This value was already present for the WIN2k3 servers in WMI.

The Script:
#Update-AD-From-WMI.ps1

#Get the required value from WMI and place in a variable.
function Update-Servers-Site
{
$Serv = gwmi win32_NTDomain -ComputerName $Server | where { $_.caption -match "COMPANYNAME"}
$site = $Serv.ClientSiteName

#Set the description with the value from the variable
Get-qadComputer $server | Set-QADObject -Description $Site | Out-Null
Get-QADComputer $server | Select Name,Description
}

#Loop through a list of server running the function against each one.
$Servers = gc C:\liveServers.txt
Foreach ($server in $Servers) {Update-Servers-Site}

Wednesday 1 July 2009

StopStart-Services

The Need:
To stop and restart a service across many computers.


The Script:
#StopStartServices.ps1
#This script will stop services and then start the services on a list of servers.

$service = Read-Host "Enter Service Name"
$ServerList = get-content (Read-Host "Please Provide Server List")

function StopService {
$ServerList | % { gwmi win32_service -ComputerName $_ -Filter "name='$Service'" | % { $_.stopservice() }} | out-null
write-host "$Service has stopped on $_"
}

Function StartService {
$ServerList | % { gwmi win32_service -ComputerName $_ -Filter "name='$Service'" | % { $_.startservice() }} | out-null
write-host "$Service has Started on $_"
}

stopservice
startservice

Write-host "All instances of $service have now restarted"

Friday 15 May 2009

Check-ActiveServers

The Need:
Today I needed to go through Active Directory and produce a list of all servers, then check which were active. I needed to output this to file this time but more often I will just need to output to the screen, so i decided to make use of the switch statement.


The Script:
cls
write-Host "This script will list all the servers in AD and then ping them."
$output = (Read-Host "Press 1 to output to the screen or 2 to output to file")

Switch ($output) {

1 {
Write-Host "Please Wait....Checking AD now!" -fore Yellow
#Get Servers from AD
$ServerList = @(get-qadcomputer -OSName "Windows Server*")
$Servers = $ServerList | foreach {$_.Name}


#Ping Server
function Ping-Server{
$ping = gwmi -q "SELECT * FROM Win32_Pingstatus WHERE Address = '$serv'"
if($ping.statusCode -eq 0) { write-Host "$serv is up" }
else { Write-Host "$serv is not responding" -fore red }
}

foreach ($serv in ($servers)){Ping-Server}
write-host "Done!"
}

2 {
Write-Host "When complete the files will be saved in C:\Temp"
Write-Host "Please Wait....Checking AD now!" -fore Yellow
#Create 3 blank files
New-Item C:\Temp\Servers-in-AD.txt -Type File -force | out-null
New-Item C:\Temp\Servers-Responding.txt -Type File -force | out-null
New-Item C:\Temp\Servers-Not-Responding.txt -Type File -force | out-null

#Get Servers from AD
$ServerList = @(get-qadcomputer -OSName "Windows Server*"); $Servers = $ServerList | foreach {$_.Name}

$Servers >> C:\Temp\Servers-in-AD.txt

#Ping Server
function Ping-Server{
$ping = gwmi -q "SELECT * FROM Win32_Pingstatus WHERE Address = '$serv'"
if($ping.statusCode -eq 0) { Write-output "$serv is up" >>C:\Temp\Servers-Responding.txt}
else { Write-output "$serv is not responding" >>C:\Temp\Servers-Not-Responding.txt}
}
foreach ($serv in ($servers))
{
Ping-Server
}
write-host "Done!"

#Open output files
Invoke-Item C:\Temp\Servers-in-AD.txt
Invoke-Item C:\Temp\Servers-Not-Responding.txt
Invoke-Item C:\Temp\Servers-Responding.txt
}
Default {Write-Host "You didn't select option 1 or 2" -fore Red}
}

Saturday 9 May 2009

Check-RemoteServices

The Need:
This week a guy at work asked me how he could query multiple servers for the status of some specific services.


The Script:
#Check-RemoteServices.ps1
#Grabs a list of servers
$Servers = (Get-Content C:\servers.txt)

#Pings each server in the list and if its up queries the services
$Servers | foreach {
$ping = gwmi win32_pingstatus -filter "address='$_'"
if($ping.statusCode -eq 0)

{
$srv = gwmi -query "select SystemName,Displayname,State,Startname,StartMode,Status from win32_service" -computer $_
$srv | Where {$_.Displayname -eq "DHCP Server"} | select SystemName,State,StartMode,DisplayName
$srv | Where {$_.Displayname -eq "DNS Server"} | select SystemName,State,StartMode,DisplayName
$srv | Where {$_.Displayname -eq "Windows Internet Name Service (WINS)"} | select SystemName,State,StartMode,DisplayName
$srv | Where {$_.Displayname -eq "SNMP Service"} | select SystemName,State,StartMode,DisplayName
$srv | Where {$_.Displayname -eq "Microsoft Exchange Information Store"} | select SystemName,State,StartMode,DisplayName
$srv | Where {$_.Displayname -eq "MSSQLServer"} | select SystemName,State,StartMode,DisplayName
}

#If the server does not respond a message is written the console
Else {write-host "$_ is not responding" -fore red}
}

Tuesday 21 April 2009

Find-Conficker

The Need:
I needed to search all servers in AD to check for the presence of a dll file dropped by the Conficker virus.


The Script:
#Find-Conficker.ps1
#Get the server list
$ServerList = @(get-qadcomputer -OSName "Windows Server*"); $Servers = $ServerList | foreach {$_.Name}; Write-host "These Servers will be checked" -fore green ; $Servers

#Ping Server
function Find-Infection{
$ping = gwmi -q "SELECT * FROM Win32_Pingstatus WHERE Address = '$serv'"
if($ping.statusCode -eq 0) { Write-Host "Checking $Serv Now" -fore Yellow;

#Check for File
gci -path \\$serv\c$\windows\system32 -filter *.dll -force | where { $_.attributes -eq "ReadOnly, Hidden, System, Archive" }
}
else { write-host "$serv is not responding" -for Red}
}
foreach ($serv in ($servers))
{
Find-Infection | select Length,Mode,FullName | ft -auto
}

Tuesday 14 April 2009

Get-Mailboxes

The Need:
Today I wanted to quickly list all mailboxes on an Exchange 2003 server without going through the hassle of a million mouse clicks in ESM. This simple script was just what I needed. It prompts me for a server then lists the mailboxes and size going from largest to smallest.



The Script:
#A simple script to look at the mailboxes on an Exchange 2003 Server.
Function Get-Mailboxes {
$ExchServer = Read-Host "Which Exchange Server?"
gwmi -namespace root\microsoftexchangev2 Exchange_Mailbox -comp $ExchServer |
select Mailboxdisplayname,Size | sort size -Descending | Format-Table -Auto
}

Saturday 4 April 2009

Get-ServiceStatus

The Need:
This week I needed to check whether a particular service (ersvc) had stopped on a number of computers. I pulled all the windows 2000 and XP computers from AD into a text file (C:\Comps.txt) with the Get-QADComputer cmdlet, then pinged each computer first. If the computer was up the script ran the check on the service, if the computer was down it ignored it.

The only output I got was computers that were up that had the service installed but was stopped.



The Script:
$comps = (Get-Content C:\Comps.txt)
function Ping-Host
{$ping = gwmi -q "SELECT * FROM Win32_Pingstatus WHERE Address = '$comp'"
if($ping.statusCode -eq 0)
{$ersvc = gwmi win32_service -comp $comp | where { $_.name -eq "ersvc"}
if ($ersvc.state -eq "stopped")
{Write-Host PC: $comp Service: $ersvc.name State: $ersvc.state}}}
foreach ($comp in ($comps))
{ping-host}

Thursday 2 April 2009

Check-Uptime

The Need:
There are several occasions when I need to check the uptime on a number of servers.


The Script:
$Servers = Get-Content "c:\Servers.txt"
Function Check-Uptime {
forEach($Server in $Servers)
{
$wmi = gwmi Win32_OperatingSystem -comp $Server
$BootTime = $wmi.ConvertToDateTime($wmi.Lastbootuptime)
[TimeSpan]$Uptime = New-TimeSpan $BootTime $(get-date)
Write-host $Server :Uptime: " $Uptime.days "Days" $Uptime.hours "Hours" $uptime.minutes "Minutes" $uptime.seconds "Seconds"
}}
Check-Uptime

Monday 30 March 2009

Reboot-Servers

The Need:
After patches have been applied to my servers I like to control the reboot schedule. To do this I break the servers down into groups of 10 or so and run the following script against each list.


The Script:
Get-Content c:\servers.txt | ForEach-Object { gwmi win32_operatingsystem -ComputerName $_ | ForEach-Object { $_.reboot() } | out-null ; write-host "$_ is going down"}

Get-RemoteCD

The Need:
When patching my servers I occasionally have an issue that I reboot a server that has a CD left in the drive and the server doesn't come back up after the reboot. I quickly wrote this script to check through a list of servers for CD Drive that have disks inserted.


The Script:
#This script checks a list of remote server to see if a CD is loaded.
$servers = Get-Content c:\servers.txt
function Get-RemoteCD
{
Foreach ($Server in ($Servers))
{
gwmi win32_cdromdrive -comp $Server | select SystemName,MediaLoaded,VolumeName | ft -auto
}}
Get-RemoteCD

Saturday 28 March 2009

Count-CitrixSessions

The Need:
Throughout the day I like to get stats on my citrix farm to make sure everything is ticking over okay. This script isn't as fast as it could be and I hope to revise it at a later date. For this script I needed to install the free citrix SDK from the citrix site.



The Script:
#Count-CitrixSession.ps1
#count citrix sessions and other useful info

$farm = new-Object -com "MetaframeCOM.MetaframeFarm"
$farm.Initialize(1)

# displays a list of published apps and the number of users on each
write-host "Total users on each citrix application" -fore yellow
$farm.sessions | select UserName,AppName | group AppName | Sort Count -desc | select Count,Name | ft -auto
$livesessions = ($farm.Sessions).count
write-host "The number of current citrix sessions is" $livesessions -fore red

write-host " "

# list of citrix servers and total number of sessions on each one
write-host "Total sessions on each citrix server" -fore yellow
$farm.sessions | select ServerName,AppName | group ServerName | sort name | select Count,Name | ft -auto

write-host " "

# To see which users have more than one session open
write-host "First 15 Users with more than one citrix session" -fore yellow
$farm.sessions | select UserName,AppName | group UserName | Sort Count -desc | select Count,Name -first 15 | ft -auto



The Update:
I found this update of my script on the WagTheReal blog. The author has edited the script to make it run about 3 times faster. He has also followed up his post with a series of posts that import the results of this into SQL. Very cool stuff indeed!


$livesessions = 0
$disconnected = 0
$farm = New-Object -com "MetaframeCOM.MetaframeFarm"
$farm.Initialize(1)

#Load Up Array for a snapshot of current sessions in CITGO
$sessionAry = @($farm.Sessions | select UserName,AppName,ServerName,SessionState)

foreach ($sess in $sessionAry) {
if ($sess.SessionState -eq "5") {$disconnected = $disconnected + 1}
else {$liveessions = $livesessions++}
}

Write-Host "The number of active citrix sessions is" $livesessions -fore red
Write-Host "The numbrer of disconnected citrix sessions is” $disconnected -fore red

Write-Host ” "

# displays a list of published apps and the number of users on each
Write-Host “Total users on top 20 citrix applications” -fore yellow
$sessionAry | group AppName | sort Count -desc | select Count,name -first 20 | ft -auto

Write-Host ""

# list of citrix servers and total number of sessions on each one
write-host “Total sessions on each citrix server” -fore yellow
$sessionAry | group ServerName | sort name | select Count,Name | ft -auto

write-host ""

# To see which users have more than one session open
write-host "First 20 Users with more than one citrix session" -fore yellow
$sessionAry | group UserName | Sort Count -desc | select Count,Name -first 20 | ft -auto


Get-NewUsers

The Need:
I have a need to know what accounts have been created within the past week/month.



The Script:
#Get-NewUsers
#This script will list new accounts and then count them.

$days = (read-host "How many days back shall I go?")
Write-host "This script will display all accounts created in the past $days days. Please wait a few minutes" -fore yellow
$date = get-date
$date = $date.AddDays(-$days)
write-host " "
$TotalAccountsCreated = Get-QADUser -SizeLimit 0 | where {$_.whenCreated -ge $date} | select Name,Company
$TotalAccountsCreated
write-host " "
Write-host "There have been" $totalaccountscreated.count "accounts created in the past $days days" -fore red

Introduction

I have created this blog so I can separate my Powershell posts from the security related posts that I make on my SynJunkie blog.

The scripts I'll be posting here are going to be simple scripts that I have put together that help me in my job as a Systems Administrator. There won't be anything too fancy and I'm sure there will be many other ways to accomplish the same task. These scripts are just purely what has worked for me at the time.

The format of the posts will be, what problem I am trying to solve and the script I have used.

Whilst getting started with scripting I have had loads of help from the guys at the Powershell Community forums and I would recommend any new user should take a look there. The PowerScripting Podcast is also an excellent source of information.