Prof. PowerShell

As many of you know, I write the popular Mr. Roboto column for REDMOND magazine. Starting in January, I will be taking on a new title, Professor PowerShell. The weekly Windows Tip Sheet column I’ve been doing for will be come Prof. PowerShell. The column will still be weekly, but will focus entirely on PowerShell. My goal is to provide a little education as well as examples of how to use PowerShell to solve real-world problems.

The column is sent out weekly as a newsletter.  Current Tip Sheet subscribers will automatically get the new column. If you’d like to get the newsletter as well, subscribe now to the newsletter.  Go to, click Get Newsletters and subscribe to News.  In addition to my column you’ll gets lots of other useful information.  Or setup your RSS reader to subscribe to the column’s feed.

Technorati Tags: ,

PowerShell Process Uptime

Not too long ago, I wrote an MCPMag Tip Sheet column on using the pipeline in PowerShell. I showed how you could get the start time of a specified service:

$svcname=Read-Host “Enter a service name” ; get-process | where {$ -eq (get-wmiobject win32_service | where {$ -eq $svcname}).ProcessID} | select -property StartTime

We can take this a step further and calculate the Uptime. Let’s look at a quick one-line example using a process:

(get-date).Subtract((Get-Process firefox).starttime)

This expression subtracts the start time property of the Firefox process from the current date and time. When executed, you should get output like this:

Days : 1
Hours : 4
Minutes : 20
Seconds : 29
Milliseconds : 506
Ticks : 1020295067859
TotalDays : 1.18089706928125
TotalHours : 28.34152966275
TotalMinutes : 1700.491779765
TotalSeconds : 102029.5067859
TotalMilliseconds : 102029506.7859

If I wanted nicer output from my one-liner I can clean it up like this:

$u=(get-date).Subtract((Get-Process firefox).starttime);Write-Host $u.Days day $u.hours hours $u.minutes minutes and $u.seconds seconds

This is one single line expression.

Since all services are associated with a process, we can find the uptime of the process and thus the service. Except for some shared services that use svchost, this should be pretty accurate. I’ve split this back up into separate expressions to make it easier to follow:

$svcname=Read-Host “Enter a service name”
$p=Get-Process | where {$ -eq (Get-WmiObject win32_service | where {$ -eq $svcname}).ProcessID} | select -property StartTime
write-host $svcname service
Write-Host $u.Days day $u.hours hours $u.minutes minutes and $u.seconds seconds

Not too shabby. The process is a little tedious because I have to query each service via WMI to get it’s associated process. To wrap this up, let’s go whole hog and report on the uptime for each running service. You’ll really need to put this in a script.

Function Get-ProcessUptime {
$p=Get-Process | where {$ -eq (Get-WmiObject win32_service | where {$ -eq $svcname}).ProcessID} | select -property StartTime
Write-Host $svcname service t $u.Days day $u.hours hours $u.minutes minutes and $u.seconds seconds

foreach ($svc in (get-service | where {$_.status -eq "running"})) {Get-ProcessUptime $}

I've put the uptime code in a function that takes a service name as a parameter. I then get a list of running services and pass each one to the function. There's probably a more efficient way to do this, but it doesn't jump out at me right now.


Get uptime for all processes:

foreach ($proc in (Get-Process | where {$ -ne "Idle" -AND $ -ne "System"})) {
Write-Host $
t $u.Days day $u.hours hours $u.minutes minutes and $u.seconds seconds

Technorati tags: , , , MCPMag, ,

Files on a diet

I did a TipSheet column recently on compacting files to save space. I thought I’d take a moment to respond to some of the comments. First, today’s hard drives are enormous and drives are cheap. However, there are still plenty of 3 and 5 year old servers that need to squeak by for a little longer. File compression gives you (maybe) a little breathing room.

As far as quotas and the like, those calculations are based on the uncompressed size. And while the preferred practice for compression is to set it at the folder level sometimes that doesn’t make sense such as dropping a 10MB jpg which won’t compress much more. The column I’m discussed gave you a technique to handle compression on a file type basis.

As with all my TipSheet columns, they are not one size fits all.

Technorati Tags:

More One Liners

I recently did a TipSheet column listing some of my favorite quick, one line commands. Reader Wayne was kind enough to share with me his list of oft-used one-liners which he graciously offered to share. I have not tested many of these personally, but you always test things in a non-production environment anyway, right? The command entry should all be on one line. I’ve wrapped lines just to get everything displayed in the post.
FSMO Roles
ntdsutil roles Connections “Connect to server %logonserver%” Quit “select Operation Target” “List roles for conn server” Quit Quit Quit
[JDH: This is really a series of steps, not a single command
Domain Controllers
Nltest /dclist:%userdnsdomain%
Domain Controller IP Configuration
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do psexec \\%i ipconfig /all
Stale computer accounts
dsquery computer domainroot -stalepwd 180 -limit 0
Stale user accounts
dsquery user domainroot -stalepwd 180 -limit 0
Disabled user accounts
dsquery user domainroot -disabled -limit 0
AD Database disk usage
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do dir \\%i\admin$\ntds
Global Catalog Servers from DNS
dnscmd %logonserver% /enumrecords %userdnsdomain% _tcp | find /i “3268”
Global Catalog Servers from AD
dsquery * “CN=Configuration,DC=forestRootDomain” -filter “(&(objectCategory=nTDSDSA)(options:1.2.840.113556.1.4.803:=1))”
Users with no logon script
dsquery * domainroot -filter “(&(objectCategory=Person)(objectClass=User)(!scriptPath=*))” -limit 0 -attr sAMAccountName sn givenName pwdLastSet distinguishedName
User accounts with no pwd required
dsquery * domainroot -filter “(&(objectCategory=Person)(objectClass=User)(userAccountControl:1.2.840.113556.1.4.803:=32))”
User accounts with no pwd expiry
dsquery * domainroot -filter “(&(objectCategory=Person)(objectClass=User)(userAccountControl:1.2.840.113556.1.4.803:=65536))”
User accounts that are disabled
dsquery * domainroot -filter “(&(objectCategory=Person)(objectClass=User)(userAccountControl:1.2.840.113556.1.4.803:=2))”
DNS Information
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do dnscmd %i /info
DNS Zone Detailed information
dnscmd /zoneinfo %userdnsdomain%
Garbage Collection and tombstone
dsquery * “cn=Directory Service,cn=Windows NT,cn=Services,cn=Configuration,DC=forestRootDomain” -attr garbageCollPeriod tombstoneLifetime
Netsh authorised DHCP Servers
netsh dhcp show server
DSQuery authorised DHCP Servers
Dsquery * “cn=NetServices,cn=Services,cn=Configuration, DC=forestRootDomain” -attr dhcpServers
DHCP server information
netsh dhcp server \\DHCP_SERVER show all
DHCP server dump
netsh dhcp server \\DHCP_SERVER dump
WINS serer information
Netsh wins server \\WINS_SERVER dump
Group Policy Verification Tool
gpotool.exe /checkacl /verbose
AD OU membership
dsquery computer -limit 0
AD OU membership
dsquery user -limit 0
List Service Principal Names
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do setspn -L %i
Compare DC Replica Object Count
dsastat –s:DC1;DC2;… –b:Domain –gcattrs:objectclass –p:999
Check AD ACLs
acldiag dc=domainTree
NTFRS Replica Sets
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do ntfrsutl sets %i
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do ntfrsutl ds %i
Domain Controllers per site
Dsquery * “CN=Sites,CN=Configuration,DC=forestRootDomain” -filter (objectCategory=Server)
DNS Zones in AD
for /f %i in (‘dsquery server -o rdn’) do Dsquery * -s %i domainroot -filter (objectCategory=dnsZone)
Enumerate DNS Server Zones
for /f %i in (‘dsquery server -o rdn’) do dnscmd %i /enumzones
Subnet information
Dsquery subnet –limit 0
List Organisational Units
Dsquery OU
ACL on all OUs
For /f “delims=|” %i in (‘dsquery OU’) do acldiag %i
Domain Trusts
nltest /domain_trusts /v
Print DNS Zones
dnscmd DNSServer /zoneprint DNSZone
Active DHCP leases
For /f %i in (DHCPServers.txt) do for /f “delims=- ” %j in (‘”netsh dhcp server \\%i show scope | find /i “active””‘) do netsh dhcp server \\%i scope %j show clientsv5
DHCP Server Active Scope Info
For /f %i in (DHCPServers.txt) do netsh dhcp server \\%i show scope | find /i “active”
Resolve DHCP clients hostnames
for /f “tokens=1,2,3 delims=,” %i in (Output from ‘Find Subnets from DHCP clients’) do @for /f “tokens=2 delims=: ” %m in (‘”nslookup %j | find /i “Name:””‘) do echo %m,%j,%k,%i
Find two online PCs per subnet
Echo. > TwoClientsPerSubnet.txt & for /f “tokens=1,2,3,4 delims=, ” %i in (‘”find /i “pc” ‘Output from Resolve DHCP clients hostnames'”‘) do for /f “tokens=3 skip=1 delims=: ” %m in (‘”Find /i /c “%l” TwoClientsPerSubnet.txt”‘) do If %m LEQ 1 for /f %p in (‘”ping -n 1 %i | find /i /c “(0% loss””‘) do If %p==1 Echo %i,%j,%k,%l
AD Subnet and Site Information
dsquery * “CN=Subnets,CN=Sites,CN=Configuration,DC=forestRootDomain” -attr cn siteObject description location
AD Site Information
dsquery * “CN=Sites,CN=Configuration,DC=forestRootDomain” -attr cn description location -filter (objectClass=site)
Printer Queue Objects in AD
dsquery * domainroot -filter “(objectCategory=printQueue)” -limit 0
Group Membership with user details
dsget group “groupDN” -members | dsget user -samid -fn -mi -ln -display -empid -desc -office -tel -email -title -dept -mgr
Total DHCP Scopes
find /i “subnet” “Output from DHCP server information” | find /i “subnet”
Site Links and Cost
dsquery * “CN=Sites,CN=Configuration,DC=forestRootDomain” -attr cn cost description replInterval siteList -filter (objectClass=siteLink)
Time gpresult
timethis gpresult /v
Check time against Domain
w32tm /monitor /computers:ForestRootPDC
Domain Controller Diagnostics
dcdiag /s:%logonserver% /v /e /c
Domain Replication Bridgeheads
repadmin /bridgeheads
Replication Failures from KCC
repadmin /failcache
Inter-site Topology servers per site
Repadmin /istg * /verbose
Replication latency
repadmin /latency /verbose
Queued replication requests
repadmin /queue *
Show connections for a DC
repadmin /showconn *
Replication summary
Repadmin /replsummary
Show replication partners
repadmin /showrepl * /all
All DCs in the forest
repadmin /viewlist *
ISTG from AD attributes
dsquery * “CN=NTDS Site Settings,CN=siteName,CN=Sites,CN=Configuration,DC=forestRootDomain” -attr interSiteTopologyGenerator
Return the object if KCC Intra/Inter site is disabled for each site
Dsquery site | dsquery * -attr * -filter “(|(Options:1.2.840.113556.1.4.803:=1)(Options:1.2.840.113556.1.4.803:=16))”
Find all connection objects
dsquery * forestRoot -filter (objectCategory=nTDSConnection) –attr distinguishedName fromServer whenCreated displayName
Find all connection schedules
adfind -b “cn=Configuration,dc=qraps,dc=com,dc=au” -f “objectcategory=ntdsConnection” cn Schedule -csv
Software Information for each server
for /f %i in (Output from ‘Domain Controllers’) do psinfo \\%i & filever \\%i\admin$\explorer.exe \\%i\admin$\system32\vbscript.dll \\%i\admin$\system32\kernel32.dll \\%i\admin$\system32\wbem\winmgmt.exe \\%i\admin$\system32\oleaut32.dll
Check Terminal Services Delete Temp on Exit flag
For /f %i in (Output from ‘Domain Controllers’) do Reg query “\\%i\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server” /v DeleteTempDirsOnExit
For each XP workstation, query the current site and what Group Policy info
@dsquery * domainroot -filter “(&(objectCategory=Computer)(operatingSystem=Windows XP Professional))” -limit 0 -attr cn > Workstations.txt & @For /f %i in (Workstations.txt) do @ping %i -n 1 >NUL & @if ErrorLevel 0 If NOT ErrorLevel 1 @Echo %i & for /f “tokens=3” %k in (‘”reg query “\\%i\hklm\software\microsoft\windows\currentversion\group policy\history” /v DCName | Find /i “DCName””‘) do @for /f %m in (‘”nltest /server:%i /dsgetsite | find /i /v “completed successfully””‘) do @echo %i,%k,%m
Information on existing GPOs
dsquery * “CN=Policies,CN=System,domainRoot” -filter “(objectCategory=groupPolicyContainer)” -attr displayName cn whenCreated gPCFileSysPath
Copy all Group Policy .pol files
for /f “tokens=1-8 delims=\” %i in (‘dir /b /s \\%userdnsdomain%\sysvol\%userdnsdomain%\policies\*.pol’) do @echo copy \\%i\%j\%k\%l\%m\%n\%o %m_%n.pol
Domain Controller Netlogon entries
for /f %i in (‘dsquery server /o rdn’) do echo %i & reg query \\%i\hklm\system\currentcontrolset\services\netlogon\parameters
WINS Statistics
for /f “tokens=1,2 delims=,” %i in (WINSServers.txt) do netsh wins server \\%i show statistics
WINS Record counts per server
for /f “tokens=1,2 delims=,” %i in (WINSServers.txt) do netsh wins server \\%i show reccount %i
WINS Server Information
for /f “tokens=2 delims=,” %i in (WINSServers.txt) do netsh wins server \\%i show info
WINS Server Dump
for /f “tokens=2 delims=,” %i in (WINSServers.txt) do netsh wins server \\%i dump
WINS Static Records per Server
netsh wins server \\LocalWINSServer show database servers={} rectype=1
Find policy display name given the GUID
dsquery * “CN=Policies,CN=System,DC=domainRoot” -filter (objectCategory=groupPolicyContainer) -attr Name displayName
Find empty groups
dsquery * -filter “&(objectCategory=group)(!member=*)” -limit 0 -attr whenCreated whenChanged groupType sAMAccountName distinguishedName memberOf
Find remote NIC bandwidth
wmic /node:%server% path Win32_PerfRawData_Tcpip_NetworkInterface GET Name,CurrentBandwidth
Find remote free physical memory
wmic /node:%Computer% path Win32_OperatingSystem GET FreePhysicalMemory
Find remote system information
SystemInfo /s %Computer%
Disk statistics, including the number of files on the filesystem
chkdsk /i /c
Query IIS web sites
iisweb /s %Server% /query “Default Web Site”
Check port state and connectivity
portqry -n %server% -e %endpoint% -v
Forest/Domain Functional Levels
ldifde -d cn=partitions,cn=configuration,dc=%domain% -r “(|(systemFlags=3)(systemFlags=-2147483648))” -l msds-behavior-version,dnsroot,ntmixeddomain,NetBIOSName -p subtree -f con
Forest/Domain Functional Levels
dsquery * cn=partitions,cn=configuration,dc=%domain% -filter “(|(systemFlags=3)(systemFlags=-2147483648))” -attr msDS-Behavior-Version Name dnsroot ntmixeddomain NetBIOSName
Find the parent of a process
wmic path Win32_Process WHERE Name=’notepad.exe’ GET Name,ParentProcessId
Lookup SRV records from DNS
nslookup -type=srv _ldap._tcp.dc._msdcs.{domainRoot}
Find when the AD was installed
dsquery * cn=configuration,DC=forestRootDomain -attr whencreated -scope base
Enumerate the trusts from the specified domain
dsquery * “CN=System,DC=domainRoot” -filter “(objectClass=trustedDomain)” -attr trustPartner flatName
Find a DC for each trusted domain
for /f “skip=1” %i in (‘”dsquery * CN=System,DC=domainRoot -filter (objectClass=trustedDomain) -attr trustPartner”‘) do nltest /dsgetdc:%i
Check the notification packages installed on all DCs
for /f %i in (‘dsquery server /o rdn’) do @for /f “tokens=4” %m in (‘”reg query \\%i\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa /v “Notification Packages” | find /i “Notification””‘) do @echo %i,%m
List ACLs in SDDL format
setacl -on %filepath% -ot file -actn list -lst f:sddl
Find out if a user account is currently enabled or disabled
dsquery user DC=%userdnsdomain:.=,DC=% -name %username% | dsget user -disabled -dn
Find servers in the domain
dsquery * domainroot -filter “(&(objectCategory=Computer)(objectClass=Computer)(operatingSystem=*Server*))” -limit 0
Open DS query window
rundll32 dsquery,OpenQueryWindow

Technorati Tags:
commandshell gpotool

Tip Sheet Thoughts

As some of you may know, I’ve started writing the weekly Tip Sheet column for It’s a short column with just enough room to get a tip or suggestion out. There’s not nearly enough room to explain my reasoning for the tip so I thought I’d jot down some thoughts about my goals and philosophy of the Tip Sheet column.
First of all the tip needs to be easy to implement.  Ideally it can be accomplished using native Windows functionality.  If not, it should be free. I know from all my years of consulting that many IT shops are run on the tightest of budgets.  Sure, there are plenty of third party vendor supplied tools that can make administering a server or network easier, but they come at a price. I’m always thinking about the overworked administrator who can barely drink a cup of coffee in the morning before the first fire erupts.  I want to publish little tips that make it easier to get the job done.
Occassionally, some tips are shortcuts and may fly in the face of IT best practices.  We all know you should monitor disk usage so that user’s don’t fill it with non-business files.  However, this takes time which I’ve already determined may be in short supply.  It’s a sad fact that scheduled maintenance tasks and best practices often fall to the wayside given the contraints of time and money.  So if you see a tip that appears to contradict a best practice or some assumed standard of system administration, be thankful you are in a position where you don’t need to take advantage of the tip.  I’m always open to feedback on my columns but think about the men and women who may be running a shop similar in size to yours but with half the budget and resources. What would their job be like on  a daily basis?  What would yours? 
My goal is to help make that job a little easier, one small tip at a time.
Technorati Tags : ,