Solved

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

Posted on 2010-11-22
9
602 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 71

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
NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

 
LVL 71

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 71

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 71

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

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

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

While rebooting windows server 2003 server , it's showing "active directory rebuilding indices please wait" at startup. It took a little while for this process to complete and once we logged on not all the services were started so another reboot is …
A project that enables an administrator to perform actions within a user session context not just at the time of login but any time later on day(s) or week(s) later.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

679 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