Showing posts with label WMI. Show all posts
Showing posts with label WMI. Show all posts

Thursday, June 4, 2009

Searching for files remotely

We are looking to possibly centralize the management of our OPT files. Thought maybe a quick script in PowerShell would do the trick. Ran the following line:

Get-childitem \\server1-vp01\c$ -Include *.opt -Recurse

and waited, waited, waited...... 6 minutes later the console displayed my results.
Knowing a little bit about WMI, I decided to approach this from a different angle:
Get-WmiObject `
-class CIM_DATAFile `
-computername 'server-vp01' `
-filter "extension='opt' and drive='c:'"
This gave me back the results in 2.73 seconds!

Comparing the times generated the following:
measure-command {`
get-childitem \\server-vp01\c$ `
-Include *.opt `
-Recurse}
Days              : 0
Hours :
0
Minutes :
6
Seconds :
3
Milliseconds :
476
Ticks :
3634762131
TotalDays : 0.00420690061458333
TotalHours : 0.10096561475
TotalMinutes : 6.057936885
TotalSeconds : 363.4762131
TotalMilliseconds : 363476.2131
measure-command {`
Get-WmiObject `
-class CIM_DATAFile `
-computername 'server-vp01' `
-filter "extension='opt' and drive='c:'"}

Days :
0
Hours :
0
Minutes :
0
Seconds :
2
Milliseconds :
739
Ticks :
27390035
TotalDays : 3.17014293981481E
-05
TotalHours : 0.000760834305555556
TotalMinutes : 0.0456500583333333
TotalSeconds : 2.7390035
TotalMilliseconds : 2739.0035
Pretty obvious which method to use.
Once again, PowerShell and WMI save the day.

Thursday, September 25, 2008

Getting Screen Resolution with WMI and PowerShell

Getting the screen resolution with PowerShell is quite simple:

param( [string]$strComputer = "." )
$displays
= Get-WmiObject `
-class "Win32_DisplayConfiguration" `
-computername $strComputer

foreach ($display in $displays) {
$obj
= New-Object psObject
$obj
Add-Member NoteProperty DeviceName $display.DeviceName
$obj
Add-Member NoteProperty PelsWidth $display.PelsWidth
$obj
Add-Member NoteProperty PelsHeight $display.PelsHeight
$obj
Add-Member NoteProperty BitsPerPel $display.BitsPerPel
$obj
Add-Member NoteProperty DisplayFrequency $display.DisplayFrequency
Write
-Output $obj
}


Setting the resolution is not so simple. There are a few ways to do this, none of them completely native to PowerShell. You can pass parameters to a compiled executable like this one listed on CodeProject or Qres (Thanks Hal for the links). If warranted, and ambition wasn't an issue, you could write inline C#. Check out Lee Holmes' Invoke-Inline for a wrapper for this.

Enjoy!

Wednesday, September 3, 2008

Print Queue Analysis - Revisited

A few weeks ago, I mentioned that I was asked to assist with the monitoring of a print queue. I have now included that PowerGadget chart. Enjoy!

function Get-PrintQueue {
$Printers
= Get-WmiObject `
-Class Win32_PerfFormattedData_Spooler_PrintQueue `
-ComputerName 'PrintServer'`
-Filter 'Name <> "_Total"'

foreach ($Printer in $Printers) {
if($Printer.Jobs -gt 1) {
$obj
= New-Object psObject
$obj
| Add-Member NoteProperty Printer $Printer.Name
$obj
| Add-Member NoteProperty JobCount $Printer.Jobs
Write
-Output $obj}
}
}
$dt
= Get-Date -Format g
Get
-PrintQueue | Out-Chart `
-Title "PrintServer printer queues as of $dt" `
-Size 800,400 `
-gallery bar `
-LegendBox_Visible false `
-View3D_Enabled true `
-AllSeries_BarShape Cylinder `
-AllSeries_PointLabels_Visible true `
-AllSeries_Color Yellow `
-Output "\\WebServer\e$\Inetpub\Extranet\Departments\InfoSys\ClinApps\HIS-Print.png"

Resulting chart:

HISPrint

Monitor Citrix Licenses

Was tasked with monitoring Citrix Licenses. We needed a way to gauge when demand was the highest and overall utilization. Following is a PowerShell script that runs every 15 minutes and stores the result in a SQL Express DB. Will be using PowerGadgets at a later point to present a graphical representation of the data.

First the function to grab the Citrix info:

Function Get-CitrixLicenses {
$Licenses
= Get-WmiObject `
-class 'Citrix_GT_License_Pool' `
-Namespace "ROOT\CitrixLicensing" `
-ComputerName $_ Select __Server, Count, InUseCount
$dt
= Get-Date -Format g
foreach ($License in $Licenses) {
$obj
= New-Object psObject
$obj
Add-Member NoteProperty Server $License.__Server
$obj
Add-Member NoteProperty Total $License.Count
$obj
Add-Member NoteProperty InUse $License.InUseCount
$obj
Add-Member NoteProperty Date $dt
Write
-Output $obj }
}


Second the DB insert function:

function Write-CitrixLicense {

BEGIN {
# Open the DB Connection
$conn
= New-Object System.Data.OleDb.OleDbConnection
$connstr
= "Your connection string"
$conn.connectionstring
= $connstr
$conn.open()

# create DB command
$cmd
= New-Object system.Data.OleDb.OleDbCommand
$cmd.connection
= $conn }

PROCESS {
# create the INSERT statement
using object properties
$now
= Get-Date -form g
$sql
= "INSERT INTO tblCitrixLicense (Server,Count,InUse,
SubmitDate) VALUES ("
$sql
+= "'" + $_.Server + "',"
$sql
+= "'" + $_.Total + "',"
$sql
+= "'" + $_.InUse + "',"
$sql
+= "'" + $now + "')"
$cmd.commandtext
= $sql
$cmd.executenonquery()
Out-Null }

END {$conn.close()}
}


Finally the call....

'Server1','Server2' %{Get-CitrixLicenses} Write-CitrixLicense

Wednesday, August 20, 2008

Print Queue Analysis

Wes - Can you tell us what printers on a particular print server have more then 10 jobs? Why yes, I can. And here is how you can do it.

$Printers = Get-WmiObject `
-Class Win32_PerfFormattedData_Spooler_PrintQueue `
-ComputerName 'hisprint-p01'`
-Filter 'Name <> "_Total"'
foreach ($Printer in $Printers) {
if($Printer.Jobs -ge 10){
Write-Host $Printer.Name $Printer.Jobs
}
}


Results:
RHS780 75
OSUHE235 15
MMCT475B 32
DNW375 74

Admittedly, this is could be much more generic. Also, a nice visual representation could be made via PowerGadgets. These are left to the reader as an exercise....

Friday, August 8, 2008

Getting Available Memory On Remote Servers

I am often asked to give total and available memory across our enterprise to our Disaster Recovery guys. Here is a simple script that achieves that goal:

$Servers = Get-Content 'c:\ProductionScripts\Servers.txt'
Write
-Host "Server,Total,Free"
foreach ( $server in $Servers )
{
$drives
= Get-WmiObject `
-Class Win32_LogicalDisk `
-ComputerName $server `
-Filter "DriveType=3" `
-ErrorAction SilentlyContinue
$size
= 0
$available
= 0
foreach($drive in $drives)
{
[
double]$size += $drive.size
[
double]$available += $drive.freespace
}

$str
= "{0},{1},{2}" -f $server,[MATH]::Round($size/1MB),[MATH]::Round($available/1MB)
Write
-Host $str
}




Thursday, June 26, 2008

ASPNet_WP.exe analysis on multiple servers via PowerGadgets


Was recently asked if I could help our development team analyze the ASPNet_WP process on 3 web servers. These 3 servers are load balanced and deliver the same content (FRS). There has been some spikes in the process and they wanted to be able to see this graphically. PowerGadgets to the rescue!

Steps are:
- Grabs an encrypted password (see previous post) as I am going across domains.
- Get WorkingSizeSet of the ASPNet_WP on the servers via WMI
- Store the WorkingSizeSet in a csv file (DB soon!)
- Grab the CSV file an pipe it to Out-Chart (PowerGadgets)
- Create a bat file that calls PowerShell with the appropriate ps1 file
(powershell.exe -nologo -command "& {c:\productionscripts\get-aspnet_wp1.ps1})
- Schedule the bat file
Please forgive the lack of pipes in this post. I am struggling to find a blog that handles code nicely.

###################################################
# Script Name: Get-ASPNet_WP.ps1
# Description: PowerShell Script for ASPNet_WP
# analysis on intapp-p2, webster-vp01
# and webster-vp02
#
# Created By: Wes Stahler
# Date Created: 6/25/2008
# Change Log:
# 6/26/2008 Added PowerGadget chart for
# inclusion on admin web page
###################################################

# Get password from encrypted file
# Once these servers are moved into the correct domain
# we won't have to worry about the creds....
$password = Get-Content c:\cred.txt ConvertTo-SecureString

# Create credentials
$creds = New-Object -typename System.Management.Automation.PSCredential `
-argumentlist "nt3osumc\stah06",$password

# Get WorkingSetSize for the 3 NT3OSUMC servers
$intapp_p2 = Get-WmiObject -Class Win32_Process `
-ComputerName intapp-p2 -Credential $creds `
Where-Object {$_.ProcessName -eq "aspnet_wp.exe"} `
Sort-Object WorkingSetSize -Descending `
Select-Object -First 1

$webster_vp01= Get-WmiObject -Class Win32_Process `
-ComputerName webster-vp01 -Credential $creds `
Where-Object {$_.ProcessName -eq "aspnet_wp.exe"} `
Sort-Object WorkingSetSize -Descending `
Select-Object -First 1

$webster_vp02= Get-WmiObject -Class Win32_Process `
-ComputerName webster-vp02 -Credential $creds `
Where-Object {$_.ProcessName -eq "aspnet_wp.exe"} `
Sort-Object WorkingSetSize -Descending `
Select-Object -First 1

# Being lazy....
$intappp2 = [math]::Round($intapp_p2.workingsetsize/1024/1024,0)
$webstervp01 = [math]::Round($webster_vp01.workingsetsize/1024/1024,0)
$webstervp02 = [math]::Round($webster_vp02.workingsetsize/1024/1024,0)
$dt = Get-Date -Format T

# Format string for to append to the historical file
# Will add to a DB later
$str = "{0},{1},{2},{3}" -f $dt,$intappp2,$webstervp01,$webstervp02

# Append to file
Add-Content -Path "c:\ProductionScripts\ASPNet_WP.csv" -Value $str

# Grab the data (last 7 hours worth) and chart!
$b = Import-Csv "c:\ProductionScripts\ASPNet_WP.csv" select -last 28
$b Out-Chart -Values Intapp-p2, webster-vp01, Webster-vp02 `
-Label Time `
-Title "ASPNet_WP.exe as of $dt" `
-gallery Lines `
-AxisY_Max 1000 `
-Size 800,533 `
-Series_1_AxisY AxesY_0 `
-Series_2_AxisY AxesY_0 `
-Output "file://intapp-p2/e$/Inetpub/Extranet/ProjectManager/Exception/ASPNet_WP.png"
###################################################

Monday, June 23, 2008

Was recently asked to retrieve hard drive (type=3) information from a supplied list of servers for backup planning.

Following is a script used to gather this information.
Now if I could only find a way to get the file count.....

function Get-DriveInventory
{
PROCESS
{
#get drives from WMI
$drives = gwmi win32_logicaldisk -comp $_ -filter "drivetype=3"
#construct output objects
foreach ($drive in $drives)
{
$obj = New-Object psobject
$obj Add-Member NoteProperty ComputerName $_
$obj Add-Member NoteProperty DriveLetter $drive.deviceid
$obj Add-Member NoteProperty VolumeName $drive.VolumeName
$free = $drive.freespace/1MB -as [int]
$obj Add-Member NoteProperty AvailableSpace $free
$total = $drive.size/1MB -as [int]
$obj Add-Member NoteProperty TotalSpace $total
Write-Output $obj
}
}
}

function Get-FileName
{
$computer = Read-Host "Filename of computer names?"
return $computer
}
# get the filename
$f = Get-FileName
Get-Content $f Get-DriveInventory Export-Csv "C:\Users\Public\Documents\DriveInventory.csv"

Wednesday, June 18, 2008

Change DNS/WINS IP on Multiple Servers

I was recently asked if I could change the DNS & WINS IP address on multiple servers via script. PowerShell to the rescue! After a brief search, I found a great post. Following is my implementation.

function Set-DNSWINS {
#Get NICS via WMI
$NICs = Get-WmiObject '
-Class Win32_NetworkAdapterConfiguration '
-ComputerName $_ '
-Filter "IPEnabled=TRUE"

foreach($NIC in $NICs) {
$DNSServers = "12.34.5.67","76.54.3.21"
$NIC.SetDNSServerSearchOrder($DNSServers)
$NIC.SetDynamicDNSRegistration("TRUE")
$NIC.SetWINSServer("12.345.67.890", "12.345.67.891")
}
}

function Get-FileName {
$computer = Read-Host "Filename of computer names?"
return $computer
}

$f = Get-FileName
Get-Content $f foreach {Set-DNSWINS}

Gotta love PowerShell!