Using Device Manager Remotely
If you’ve got servers running the Server Core version of Windows Server, you’ll probably find yourself needing to look at what devices and drivers are installed at some point. You can do this with various command line tools, but, that’s a non-trivial exercise on a good day. Instead, with a bit of configuration work, you can just use Device Manager remotely.
To do this, you’ll need to configure a Group Policy setting for the affected servers:
Computer Configuration \ Policies \ Administrative Templates \ System \ Device Installation \ "Allow remote access to the Plug and Play interface”
Set the value to enabled:
If you don’t do this, you’ll get an error similar to the following:
---------------------------
Device Manager
---------------------------
Unable to access the computer SERVER01
Make sure that this computer is on the network, has remote administration enabled, and is running the "Plug and Play" and "Remote registry" services.The error was: Access is denied.
---------------------------
OK
---------------------------
Once you’ve got things in place and the policy is effective, you can use Computer Management to target a remote machine and use the Device Manager snap-in:
---------------------------
Device Manager
---------------------------
Device Manager is running in read-only mode because you are running it on a remote computer. To uninstall devices or to change device properties or drivers, you must run Device Manager on the computer where you wish to make changes.
---------------------------
OK
---------------------------
You won’t be able to make changes, but, you’ll certainly be able to view all of the relevant details.
Conferences I’ll Be At – 2012 First Half
My calendar is starting to shape up for 2012. If you’re going to be at any IT shows in the first half of the year, here’s where you’ll find me presenting:
- Next week – Oslo, Norway for the Nordic Information Conference
- March 18 – 20 – Ontario, CA for CISOA SecureIT
- March 26 – 29 – Las Vegas for Windows Connections
- April 29 – May 2 – San Diego for The Experts Conference
TechEd is on the radar for a visit at least, but, not confirmed.
If you’re at any of these shows, stop by and say hello!
2011 in Review
Happy New Years! I’ve put something up here the past couple years as I wrap up and kick off the new year, so I thought I’d do that again. I had the pleasure of visiting customers, presenting at conferences, and taking a couple quick vacations all over the place last year. I managed to stay mostly in the US this year:
…save for a couple overseas trips:
All told, ~116,406 miles and 90 plane rides.
I sent a mail out to quite a few people who had asked about pictures from all these trips, and I thought I’d share that here – something I’ve not done before.
On the road to San Francisco from Eureka, CA in late March. The road signs called for snow chains which our rented Toyota Camry was sorely lacking. Fortunately the snow was light.
The Grapevine, driving down the 5 to Los Angeles from Bakersfield, CA.
Seals on the beach – driving up Pacific Coast Highway from San Luis Obispo, CA.
On the road from San Luis Obispo, CA to Monterey, CA – driving through Big Sur
On the road to Monterey
The Lone Cypress at Pebble Beach – I had a couple hours to do 17 mile drive before my flight out of Monterey. CA. The airport at Monterey, by the way, has a great little outdoor bar on top of the ramp area.
The Concha y Toro vineyard in Santiago, Chile is conveniently accessible from downtown by Subway.
Viña del Mar about 1:30 drive outside of Santiago, Chile
A somewhat questionable Ascensor I rode down the hill in the port of Valparaiso, Chile
Death Valley – the lowest point in the North America.
Salt Flats in Death Valley – the land of $5.33/gallon for regular gasoline
Another conference week…
The Grand Canyon from a Helicopter. Pat Richard and I did this in October – highly recommended.
The Hoover Dam, by Helicopter
Happy Trails and Best Wishes for a great 2012!
Ping a List of Servers with PowerShell
I needed to quickly get the IP addresses of about 100 servers from their names. PowerShell doesn’t appear to have a native Ping cmdlet, but, .Net certainly does. I pasted all the servers into a text file, one per line, and rand the following little loop:
$servers = Get-Content .\serverList.txt
$ping = New-Object System.Net.NetworkInformation.Ping
foreach($s in $servers)
{
$("$s,$($ping.Send($s).Address)")
}
This loop outputs a comma delimited list of ServerName,IP to the window like this:
TEST-SF6,10.12.3.96
W2003TEST,10.1.34.80
W2003TEST2,10.8.51.27
I pasted the list into a new email in Outlook, highlighted it, and then used the Convert Text to Table feature in Word (and Outlook):
Word turned my pasted CSV list into a nice table and I sent it off.
Thoughts on Building a Server Image
Repeatable, consistent, and predictable are three things that add an incredible amount of value in IT, and building servers from a base image is one way to deliver on this. I was just replying to a thread on a discussion alias where the person who started the thread had reviewed a blog post (http://www.jasonsamuel.com/2010/05/07/how-to-build-a-vmware-vsphere-vm-template-for-windows-server-2008-r2/) on how to build such an image for VMWare. I and a number of people disputed the recommendations made in the referenced blog post in addition to the various other things the individual who started the thread was planning to install in his image/template.
At a high level, the most important thing from my reply, I think, is that you should not be customizing a server for it to be convenient to your work style. The server is there for a purpose driven task. You shouldn’t even be connected to it via Remote Desktop (or sitting at the console) unless you’re troubleshooting a problem which can only be investigated from the desktop. What this means is that all the little utilities and tweaks you have on your desktop should stay on your desktop. Things like PDF readers, Internet Explorer customizations, screensavers and colors, and taskbar preferences, etc. First and foremost, many of these tweaks are profile specific so when you login with a domain account later, after running sysprep, the tweaks will be gone unless you push them into the default profile and in turn push them on to all users. Secondly, when you move on to the next big opportunity, your successor shouldn’t be expected to inherit and adapt (or spend weeks undoing) your personal preferences.
As far as system settings (e.g. page files, network settings, etc.), tweaking or disabling things just because some random guy on the Internet (including me) told you to is not a great idea. When you install an application from a vendor, be it Microsoft or any third party ISV, chances are they made assumptions in their testing that the OS is in a state relatively close to the default install. When you start disabling services (e.g. Indexing, Print Spooler, etc.) by default in an image, you provide a baseline that doesn’t meet this assumption. Rather than customizing by default, customize for specific applications. The settings in an image should be the ones required to operate at a minimum level of functionality on your network (e.g. maybe you need some custom DNS search suffixes to join the domain or settings to meet security standards). This extends to most any system level default. When you’re looking at changing a default setting, I’d first stop and ask yourself “why?”. What’s the reason this is being changed? Next, consider whether or not it should be or needs to be hardcoded in the image or if you can simply apply that configuration change via Group Policy. Anything hardcoded will require you to come back and update and re-test, and re-release the image when the value needs to be changed, whereas a Group Policy setting is easily tweaked centrally.
Inevitably there are various tools, gadgets, trinkets, etc., which make troubleshooting easier. My experience is that a great many of these tools don’t require installation and will simply run from a network share. Rather than caching tools locally on each server, or installing individual copies, put them out on a share that you can access from any machine. This way you only need to refresh one location when a tool gets updated and you also aren’t installing essentially random software on servers on an as-necessary basis. As soon as those installs aren’t consistent across all servers, you start permuting your test matrix. Personally the only thing I consistently install on a server build is Netmon or Wireshark and occasionally BgInfo (Sysinternals).
Active Directory, 4th Edition Updates
Over the past couple years, readers have identified a number of mistakes that unfortunately made it through the edit cycles for Active Directory, 4th Ed. O’Reilly recently launched a process by which authors can make updates to the source files that they use to produce eBooks and print conventional paper books on demand. I took advantage of this a few weeks ago and I resolved all of the errata which were reported as well as a couple I found myself. Here’s the quick summary on where the updated text can be found:
Print Copies - If you’ve bought a print copy, you’ll need to look at the notes I made on the errata page. However, as O’Reilly is now doing print on demand for this title, the updates will trickle out into the supply chain over time and newly purchased books will be updated. Obviously this timeline is highly dependent on how much inventory is sitting in warehouses.
eBooks - If you bought any of the various eBook formats O’Reilly offers in their web store – PDF, mobi, and ePub – then you’ll be able to login to your account and pull an updated copy down. I’m told you will also be getting an email sometime soon (if it hasn’t gone out already) notifying you of this as well. If you purchased the book for Kindle from Amazon, Amazon doesn’t have a mechanism to push updated content to your Kindle, so you won’t get an update. This also applies if you bought the book for iPhone/iPad from the Apple bookstore. The iPhone/iPad “app” version of the book is also not going to get updated due to the shift to the native Apple Bookstore.
Active Directory Group Nesting Reference
There was an unfortunate layout error in Active Directory, 4th Edition which caused the tables in Chapter 2 which explain group nesting to have the column headings over the wrong columns. This of course changes the meaning and makes the tables less than helpful. I’ve gone ahead and pasted the tables and captions below with the correct column headings.
| Can contain domain local | Can contain domain global | Can contain universal | |||||
|---|---|---|---|---|---|---|---|
| Scope | Type | Distribution groups | Security groups | Distribution groups | Security groups | Distribution groups | Security groups |
| Domain local | Distribution groups | Yes | Yes | Yes | Yes | Yes | Yes |
| Security groups | Yes | Yes | Yes | Yes | Yes | Yes | |
| Domain global | Distribution groups | No | No | Yes | Yes | No | No |
| Security groups | No | No | Yes | Yes | No | No | |
| Universal | Distribution groups | No | No | Yes | Yes | Yes | Yes |
| Security groups | No | No | Yes | Yes | Yes | Yes | |
| Group scope | Can contain users and computers from | Can contain domain local groups from | ||
| Same domain | Different domain | Same domain | Different domain | |
| Domain local groups | Yes | Yes | Special | No |
| Domain global groups | Yes | No | No | No |
| Universal groups | Yes | Yes | No | No |
Table 2-7. Restrictions on group membership based on group scope
| Group scope | Can contain domain global groups from | Can contain universal groups from | ||
| Same domain | Different domain | Same domain | Different domain | |
| Domain local groups | Yes | Yes | Yes | Yes |
| Domain global groups | Special | No | No | No |
| Universal groups | Yes | Yes | Yes | Yes |
Table 2-8. Restrictions on group membership based on domain
Web Site Updates
I made a number of improvements to the website this weekend. The major change is that I moved from the in-box commenting in Graffiti to Disqus. I’ve been having issues with the comment system for a couple of months, and Disqus adds quite a bit of functionality. I was able to port over all of the comments with metadata intact, but, trackbacks and pingbacks are currently still going against the local database. I’ve tested in IE9 and Firefox 5/6, but, I haven’t validated other browsers. Let me know if there are any layout bugs or other issues.
For the curious, Release Notes:
Fixes
- Fixed CSS bugs causing all text to be highlighted on mouse-over in comment area
- Fixed HTML bug causing footer not to span complete page in some scenarios
- Fixed CSS bug causing highlighted code to be indented
- Removed favicon.ico from 1.3 upgrade
- Removed IE7 compatibility mode header
- Removed category level RSS autodiscovery publishing
- Changed Tag RSS autodiscovery publisher to include “Tag” in title
- Replaced checked binaries with release build files
New Functionality
- Replaced commenting infrastructure with Disqus
- Updated syntax highlighter to latest release
- Replaced PowerShell syntax highlighter brush with a better one from PoshCode site
Add Office 365 Exchange Online to your PowerShell Profile
The Exchange Online component of Office365 as well as Live@EDU exposes a variant of the Exchange Management Shell that you’d normally use if you were managing an on-premises Exchange 2010 organization. Connecting to it requires a few steps which are documented here. I’ve been pasting in the three commands one at a time now for months and it’s gotten rather annoying. A bit of research reveals that you can add custom PowerShell code that is available anytime you launch a shell by modifying your PowerShell profile. You can read more about the various profiles you can modify here, but, I decided to simply modify the one specific to my user account. To do this, open a new PowerShell window and run this command:
notepad $PROFILE
If you haven’t done this before, notepad will prompt you to create a new file. Plug this code in the resultant file:
function Connect-ExchangeOnline
{
$LiveCred = Get-Credential
$global:Session365 = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection
Import-PSSession $global:Session365
}
function Disconnect-ExchangeOnline
{
Remove-PSSession $global:Session365
}
Save and restart PowerShell, and you’ll be able to run Connect-ExchangeOnline to connect to Exchange Online/Live@EDU in one easy step.
Script to Collect Hardware Inventory Data
The VBScript below will collect a number of hardware demographics from machines and output them to a CSV file. These demographics include:
- Hostname
- Serial Number
- Make
- Model
- BIOS Version
- Operating System
- CPU
- Memory (MB)
- Disk Drives
You’ll need to supply an input file with one hostname or fqdn per line. You can configure the input and output files on lines 14 and 15 of the script.
'==========================================================================
' NAME: Script to Collect Serial Number, Make, Model, Color, etc.
'
' AUTHOR: Brian Desmond
' DATE : 10/22/2006
' DATE : 7/16/2007 - added cpu, memory, disk, and error handling
'==========================================================================
Option Explicit
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
Const PATH_TO_INPUT = "Machines.txt"
Const PATH_TO_OUTPUT = "MachineInventory.csv"
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Dim shl
Set shl = WScript.CreateObject("WScript.Shell")
Dim input
Set input = fso.OpenTextFile(PATH_TO_INPUT)
Dim output
Set output = fso.CreateTextFile(PATH_TO_OUTPUT, True)
output.WriteLine "Hostname,Serial Number,Make,Model,BIOS Version,Operating System,CPU,Memory (MB),Disk Drives"
Dim wmiService
Dim wmiResults
Dim hostname
Dim make
Dim model
Dim biosversion
Dim operatingSystem
Dim serialNumber
Dim cpu
Dim memory
Dim drives
Dim line
Dim exec
Dim pingResults
While Not input.AtEndOfStream
line = input.ReadLine
hostname = ""
make = ""
model = ""
biosversion = ""
operatingSystem = ""
serialNumber = ""
cpu = ""
memory = ""
drives = ""
Set exec = shl.Exec("ping -n 2 -w 1000 " & line)
pingResults = LCase(exec.StdOut.ReadAll)
If InStr(pingResults, "reply from") Then
WScript.Echo "Reply From: " & line
On Error Resume Next
Set wmiService = GetObject("winmgmts:\\" & line & "\root\CIMV2")
If Not Err.Number = 0 Then
output.WriteLine line & ",Error: " & Err.Description
WScript.Echo line & ",Error: " & Err.Description
On Error GoTo 0
Else
On Error GoTo 0
hostname = line
Set wmiResults = wmiService.ExecQuery("SELECT * FROM Win32_BIOS", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
Dim item
For Each item In wmiResults
serialNumber = Trim(item.SerialNumber)
biosversion = Trim(item.SMBIOSBIOSVersion)
Next
Set wmiResults = wmiService.ExecQuery("SELECT * FROM Win32_ComputerSystem", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each item In wmiResults
make = Trim(item.Manufacturer)
model = Trim(item.Model)
Next
Set wmiResults = wmiService.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each item In wmiResults
operatingSystem = Trim(item.Name)
operatingSystem = Split(operatingSystem, "|")(0)
memory = Round(Trim(item.TotalVisibleMemorySize) / 1024, 2)
Next
Set wmiResults = wmiService.ExecQuery("SELECT * FROM Win32_Processor", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each item In wmiResults
cpu = Trim(item.Name)
Next
Set wmiResults = wmiService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType=3", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each item In wmiResults
drives = drives & Trim(item.DeviceID) & " " & Round(Trim(item.Size) / (1024^2), 2) & ";"
Next
output.WriteLine hostname & "," & serialNumber & "," & make & "," & model & "," & biosversion & "," & operatingSystem & "," & cpu & "," & memory & "," & drives
WScript.Echo hostname & "," & serialNumber & "," & make & "," & model & "," & biosversion & "," & operatingSystem & "," & cpu & "," & memory & "," & drives
End If
Else
output.WriteLine line & ",No Response"
WScript.Echo line & ",No Response"
End If
Wend
output.Close
input.Close
Set wmiService = Nothing
Set wmiresults = Nothing
