asked on
How to determine if .NET is being actively used?
I've been tasked with removing old/outdated versions of .NET from some of our servers that we've found to have multiple versions of .NET installed. Prior to removing the older versions of .NET - I want to verify that they are not actually being utilized by anything running on the server.
I understand that I can use the Get-ChildItem IIS:\AppPools PS command to get a view of any application running under the .NET application pools, but is this the best/only way to validate that nothing else on these servers is running under .NET?
In general use Get-Process to list the processes with this powershell script:
$processes = Get-Process | Where-Object {$_.Modules -match "mscor"}
foreach ($process in $processes)
{
Write-Host "Process Name: $($process.ProcessName)"
Write-Host "PID: $($process.Id)"
Write-Host "File Path: $($process.Path)"
Write-Host " "
}
This will get you a list of all running processes, and then filters that list by processes that have a module loaded with "mscor" in the name, which is an indicator that the process is using .NET. For each process that meets this criteria, the script will output the process name, process ID, and file path.
As for the application pools you can run this script:
$appPools = Get-ChildItem IIS:\AppPools | Select-Object -Property Name, ManagedRuntimeVersion
foreach ($appPool in $appPools)
{
Write-Host "Application Pool Name: $($appPool.Name)"
Write-Host "Used .NET Version: $($appPool.ManagedRuntimeVersion)"
Write-Host " "
}
It uses the Get-ChildItem cmdlet to get a list of all application pools in IIS, and filters that list by application pools with names that contain ".NET" and displays the .NET version being used.
Cheers
@dfke - some issues with that approach:
1. Getting the current process list is fine, but that won't capture any programs that DO run but might not be running at the time that you check the process list. There may be applications that do polling so they only run every X minutes or hours or something. Or there may be integration points that execute some script / application under certain circumstances.
2. .NET applications can have a mixed-mode execution where the executing assembly is using .NET 4.8 but is referencing an assembly that utilizes .NET 3 (and worse, it might not load up the assembly until it needs to use it), so the managed or image runtime version can be misleading.
There are a bunch of edge cases here.
There are a bunch of edge cases here.This is one reason for choosing a declarative way.
ASKER
Try C#, this uses WMI to get a list of all the running processes, including the .NET runtime version for each process. This will give you a comprehensive list of all the running applications, regardless of whether they are running continuously or just executing on demand.
using System;
using System.Management;
namespace GetProcessesAndRuntime
{
class Program
{
static void Main(string[] args)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
foreach (ManagementObject obj in searcher.Get())
{
string[] args1 = { string.Empty, string.Empty };
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", args1));
if (returnVal == 0)
{
Console.WriteLine("Process: " + obj["Name"]);
Console.WriteLine("Owner: " + args1[0]);
Console.WriteLine(".NET runtime version: " + obj["ExecutablePath"]);
}
}
}
}
}
Cheers
If you're not 100% sure of every application that runs, then it complicates things. Your main concern is going to be any programs that do not run all the time. Maybe they're scheduled or maybe they are triggered by some activity and they do some task and finish within milliseconds so any kind of polling task manager is likely to miss them unless it's very lucky.
Personally, I'd approach this by dumping a list of every .exe and every .dll in the filesystem to a file. Then run ildasm.exe (.NET decompiler that is part of the .NET SDK) against every file in the list to dump the headers.
ildasm.exe /text file.exe /noil /headers >> c:\temp\ildasm.log
In the output you should see a version string that indicates the targeted .NET framework.
It's pretty rare to find any .NET 3.x or earlier assemblies, so you might not find any at all.
Once you have a list of the old assemblies, load up procmon (Microsoft Process Monitor) and filter it down to only entries that touch those old assemblies and check the option to drop filtered rows, then let it run for the day. You should be able to see if anything accessed those files in any way.