How to check a specific version of .net present in all my DCs?

Hi Friends,

Here I’m again with a new question.

I’m in bit of a trouble to find a proper script or way to know the version of .net installed in all my Domain Controllers in a forest.

This even includes 2008 & 2008 R2 servers in it. As I’m still at beginner level into Powershell, I tried looking into forums & did a lot of googling to get some proper answers but unfortunately didn’t get one yet.

When I say all my DCs, my forest contain more than 3 hundreds of them.

Can someone please help me here or guide me with some examples or to the right direction where I can get some assistance on this please.

Peace & Cheers,
Sammy Boy.

One way to solve your problem is to use DSC to force a state of enabled / disabled of the required .Net versions on each of the DC from a single configuration file.

One solution to your problem might be to use DSC and force all your DC to right version by setting the required state of a particular .Net version.

As a POSH beginner, DSC is a bit much to bite off on.

You can just poll the registry of each system to get this information.
There are already existing scripts on the MS website for you to do such an effort. Just tweak as needed.

Detect .NET Framework versions installed
This script reports the various .NET Framework versions installed on the local or a remote computer. It queries the registry for the information (Remote Registry is required for querying the remote computers), and lists the .NET Framework version and it’s build.

Or depending on what version of PoSH you have installed, just ask PoSH directly.


…but the registry if the most specific, because the above has come caveats.

or this way.

Get-ChildItem -Path “$env:windir\Microsoft.NET\Framework\v*” |
sort lastwritetime -desc |
Format-Table -AutoSize

Directory: C:\Windows\Microsoft.NET\Framework

Mode LastWriteTime Length Name

d---- 11/11/2017 4:43 AM v4.0.30319
d---- 9/14/2017 3:10 AM v2.0.50727
d---- 4/19/2017 5:43 AM v1.0.3705
d---- 4/18/2017 9:16 PM v3.5
d---- 4/18/2017 8:29 PM v3.0
d---- 8/22/2013 11:39 AM v1.1.4322

If you need to update the .Net version, then software distribution / configuration efforts via GPO, System Center, DSC, etc. will get you there.

So I used this script as a starting point. I won’t share my script, it was a one and done. This has a lot of information and provide the details I think you need. Might need to update this script for any newer versions of .Net out there since.

These links helped me find each version of .Net
How to determine the .Net framework installed
a. Matrix:

If you are really stuck, I could share my script, but not sure it is ready for prim-time sharing. I think the first link with the function could be used against many servers if modified as necessary. Good luck.

Thank you friends for the all the help.

This actually helps. I tried making my way with all your help (most of it is just copy-paste though) and still working to get the information in the way I need it.

Something like the below one:

$myForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$dclist = $myforest.Sites | % { $_.Servers }

foreach ($dcname in $dclist) {

$source_dc_fqdn = ($dcname.Name).tolower()

    gci 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' | 
        sort pschildname -des | 
foreach-object {$; $_.GetValue("Version");}


The problem is that it does give me the list of all the versions & firmware installed on my remote DCs but doesn’t give me information of the Hostname of the DCs against which they belong.

@JohnM: Please see if this is something which is included in your script already. If so, I’d love the helping hand here.

Peace & Cheers,
Sammy Boy

OK. Not sure you are going to be able to do it the way you have it. .Net 4.x has a client and a Full version and the keys are slightly different (see second link above).

What I did in my script was create a PSCustomObject with server name, and value. Then using the script linked above as a starting point, got the values and added them to the corresponding object property. Once they are in this object you can just write this to the Pipeline and/or do something with the results.

So my Object looked like this

$Obj = [PSCustomObject]@{ 
          'ServerName'  = $Null;
               'Net10'  = $Null;
               'Net20'  = $Null;
               'Net30'  = $Null;
               'Net35'  = $Null;
               'Net40C' = $Null;
               'Net40F' = $Null;

loop thru your server list, add the server name to the $Obj.servername, query each of the reg keys, and populate your corresponding version $Obj value. Be sure to zap it at the top of your loop so missing values are not carried over from previous iterations.

Sometimes you can just add the $Obj to an array, but really there is no good reason to do that. Use the pipeline instead.

Good Luck!

Thank you all. I got what I needed.

Thanks a ton. You guys rock!!

Sorry to buzz you all again. But, I’ve got Till here and I’m loosing my mind now…

I created a simple script which look at all my remote DCs and check the .Net Version which the machine has and give me the output.

But the trouble is that my $dcname variable is completely negated in the Write-Output and give me the output without the my DCName.

Below is the script which I wrote:

$myForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() 
$dclist = $myforest.Sites | ForEach-Object { $_.Servers } 

foreach($dcname in $dclist) 
      Invoke-Command -ComputerName $dcname.Name -ScriptBlock {
        $NetRegKey = Get-Childitem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'
        $Release = ($NetRegKey).GetValue("Release")
		if ($Release -eq 461310)
          {Write-Output "$dcname is using .Net v4.7.1"}
			elseif ($Release -eq 461308) 
			{Write-Output "$dcname is using .Net v4.7.1-Win 10 Fall Creators Update"}
			elseif ($Release -eq 460805) 
				{Write-Output "$dcname is using .Net v4.7"}
				elseif ($Release -eq 460798) 
				{Write-Output "$dcname is using .Net v4.7-Win 10 Creators Update"}
				elseif ($Release -eq 394806)
					{Write-Output "$dcname is using .Net v4.6.2"}
					elseif ($Release -eq 394802)
					{Write-Host "$dcname is using .Net v4.6.2-Win 10 Anniversary Update"}
					elseif ($Release -eq 394271)
						{Write-Output "$dcname is using .Net v4.6.1"}
						elseif ($Release -eq 394254)
						{Write-Output "$dcname is using .Net v4.6.1-Win 10 November Update Systems"}
						elseif ($Release -eq 393297) 
						{Write-Output "$dcname is using .Net v4.6"}
					elseif ($Release -eq 393295) 
						{Write-Output "$dcname is using .Net v4.6-Win 10 Systems"}
					elseif ($Release -eq 379893)
					{Write-Output "$dcname is using .Net v4.5.2"}
				elseif ($Release -eq 378758) 
					{Write-Output "$dcname is using .Net v4.5.1-Win Vis,7 & 8"}
				elseif ($Release -eq 378675) 
				{Write-Output "$dcname is using .Net v4.5.1-Win 8.1"}
			elseif ($Release -eq 378389) 
				{Write-Output "$dcname is using .Net v4.5"}
              	else {
                    Write-Host "v4.5 or later is not installed on $dcname"


Below is the output which I get were the $dcname information is missing.

is using .Net v4.6.2-Win 10 Anniversary Update
is using .Net v4.6.2-Win 10 Anniversary Update
is using .Net v4.5.1-Win 8.1
is using .Net v4.5.1-Win 8.1


Kindly let me know if I’m missing something due to which my variable is not considered in the Write-Output cmdlets.

Peace & Cheers,
Sammy Boy.

Don’t see your code in here, but instead of all those IF…ElseIF might want to use a CASE statement instead to be neater.

Next since you are using invoke-command that is running on the remote server. So the variable $dcname is local to your computer and it does not exist on the remote computer. That is why it is blank.

Try using $env:computername instead of $dcname …

Good luck!

PS: I still think I prefer the PSCustomObject method. Offers more flexibility down the line.

It worked…!!! Thank you… Thank you… Thank you…

So, does $env: works only because I used Invoke-Command or it will work everytime elsewhere…

Peace & Cheers,
Sammy Boy