Solved

How can I use powershell to output version of .net installed on AD servers

Posted on 2010-11-22
9
600 Views
Last Modified: 2012-05-10
Hi,
I need to collate a list of all servers in my AD (2K, 2K3, 2K8) with their associated .NET framework version.  I also need this to inlude which servers don't have .NET installed also.  I'm new to powershell, but keen to use this as it's the new up and coming scripting tool.  I would alos prefer if the script doesn't point directly to a flat file for server names, but AD itself.
Thanks,
Can anyone also recommend any good cbt's on powershell?
0
Comment
Question by:meepmaker
  • 4
  • 3
9 Comments
 
LVL 70

Expert Comment

by:Chris Dent
ID: 34196013
Hello there,

What would you like to use to query AD? Choices are:

Quest AD CmdLets - Free, must be installed: http://www.quest.com/powershell/activeroles-server.aspx
MS AD CmdLets - Free, Win 7 / 2008 R2 only (Add Feature)
System.DirectoryServices - Free, native (all PS versions), not so easy to use

I can provide samples for any / all of the above if you wish.

To get the .NET version I've built the function below. I'm not sure how accurate it will be, perhaps you can test it?

We're reliant on the remote registry service, depending on OS that may or may not be started. The function below can start it for you provided it's not disabled.

To call it:
# Local computer
Get-DotNetVersion
# Remote computer
Get-DotNETVersion -Computer somethingelse
# To have it start up the remote registry service (and stop it afterwards)
Get-DotNETVersion -Computer somethingelse -StartRemoteRegistry

Open in new window

HTH

Chris
Function Get-DotNETVersion {
  Param(
    [String]$ComputerName = $Env:ComputerName,
    [Switch]$StartRemoteRegistry
  )

  If ($StartRemoteRegistry) {
    $ShouldStop = $False
    $Service = Get-WmiObject Win32_Service -Filter "Name='RemoteRegistry'" -Computer $ComputerName
    If ($Service.State -eq "Stopped" -And $Service.StartMode -ne "Disabled") {
      $ShouldStop = $True
      $Service.StartService() | Out-Null
    }
  }

  Try { $BaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $ComputerName) } Catch { }
  If ($?) {
    $BaseKey.OpenSubKey("Software\Microsoft\NET Framework Setup\NDP").GetSubkeyNames() | Where-Object { $_ -Match 'v\d.*' }
  }

  If ($StartRemoteRegistry -And $ShouldStop) {
    $Service.StopService() | Out-Null
  }
}

Open in new window

0
 

Author Comment

by:meepmaker
ID: 34201423
Hi Chris,

I think the System.DirectoryServices would be the best, so we don't have the reliance on another 3rd party app.  As far as I know the remote registry isn't disabled on any servers, so that isn't an issue.  I'm sure that the remote registry is as default on most servers & the few ones left I can manually check.

Thanks,
Michael
0
 
LVL 10

Expert Comment

by:wls3
ID: 34205785
Two main steps: 1) get all machines in the domain

https://blogs.technet.com/b/heyscriptingguy/archive/2006/11/09/how-can-i-use-windows-powershell-to-get-a-list-of-all-my-computers.aspx

Once you have the list, 2) loop through the $machine.name collection using a directory search:

http://www.eggheadcafe.com/software/aspnet/33178061/check-the-net-version-existing-on-the-server.aspx

If would look something like this:

$path = "\\" + $machine.name + "\c$\windows\microsoft.net\framework"
$installationlist = dir -Path $path | select fullname

Then, simply iterating the $installationlist variable will list all machines and framework versions.
0
Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 70

Accepted Solution

by:
Chris Dent earned 500 total points
ID: 34205842

Sorry, I got a bit distracted. This is the DirectoryServices method.

Chris
Function Get-DotNETVersion {
  Param(
    [String]$ComputerName = $Env:ComputerName,
    [Switch]$StartRemoteRegistry
  )

  If ($StartRemoteRegistry) {
    $ShouldStop = $False
    $Service = Get-WmiObject Win32_Service -Filter "Name='RemoteRegistry'" -Computer $ComputerName
    If ($Service.State -eq "Stopped" -And $Service.StartMode -ne "Disabled") {
      $ShouldStop = $True
      $Service.StartService() | Out-Null
    }
  }

  Try { $BaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $ComputerName) } Catch { }
  If ($?) {
    $BaseKey.OpenSubKey("Software\Microsoft\NET Framework Setup\NDP").GetSubkeyNames() | Where-Object { $_ -Match 'v\d.*' }
  }

  If ($StartRemoteRegistry -And $ShouldStop) {
    $Service.StopService() | Out-Null
  }
}

# This value is optional
$SearchRoot = [ADSI]"LDAP://OU=somewhere,DC=domain,DC=com"
# This value must be defined, although only the objectCategory filter is required
$LdapFilter = "(&(objectCategory=computer)(operatingSystem=*server*))"

$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $LdapFilter)
$Searcher.PageSize = 1000

$Searcher.FindAll() | Select-Object @{n='Name';e={ $_.Properties["name"][0] }},
  @{n='DotNETVersion';e={ Get-DotNETVersion -ComputerName $($_.Properties["name"][0]) }}

Open in new window

0
 

Author Comment

by:meepmaker
ID: 34213255
Hi Chris,

I saved the script as a .ps1 file, pointing it to AD and run it within the powershell window, but I got the following error message below, any ideas:

Exception calling "FindAll" with "0" argument(s): "A referral was returned from the server.
"
At C:\Get App\Get_DotNET_Version.ps1:34 char:18
+ $Searcher.FindAll( <<<< ) | Select-Object @{n='Name';e={ $_.Properties["name"][0] }},

0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 34213264

It means this value is incorrect:

$SearchRoot = [ADSI]"LDAP://OU=somewhere,DC=domain,DC=com"

I should have added to the note that the line should be commented out or removed if you do not wish to set it.

Chris
0
 

Author Comment

by:meepmaker
ID: 34213464
Hi Chris,
Just commented it out, but I got the following error with each server found:

Select-Object : The term 'Try' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.
At C:\Get App\Get_DotNET_Version2.ps1:34 char:36
+ $Searcher.FindAll() | Select-Object  <<<< @{n='Name';e={ $_.Properties["name"][0] }},


0
 
LVL 70

Expert Comment

by:Chris Dent
ID: 34213894

You must be using PowerShell version 1? Try only came about with 2. Upgrade possible? I haven't got PS 1 around anywhere to test things against.

The upgrade package is here (it's part of the management framework core):

http://support.microsoft.com/kb/968930

Chris
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Problem to refer to value 8 50
Set up secondary Domain Controller 4 71
Cant remote powershell into server 3 22
Domain administrator account is locked out 31 57
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This article runs through the process of deploying a single EXE application selectively to a group of user.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question