Earlier this year I blogged about the automatic maintenance task in Windows Server 2012 R2 being EVIL, today it's time for .NET Runtime Optimization Service spiking the CPU on one of my domain controllers after installing updates. Also happens when using the (quite new) November 2014 media for Windows Server 2012 R2 that includes several updates.
Update 2015-01-06: Added PowerShell snippets posted by Arjan Mensch and Keith Garner. Thanks!

After some research (Google), I realized I was not alone
The fix turned out to be easy. Find a command prompt, navigate to the C:\Windows\Microsoft.NET\Framework\v4.0.30319 folder, run the following command:
ngen.exe executequeueditems
Then have some coffee, and once the command completes, reboot the server.
PowerShell to the rescue
After posting this info, Arjan Mensch and Keith Garner kindly posted (in the comments) a quick PowerShell snippet to loop through all Framework versions and run ngen.exe.
# Code snippet from Arjan Mensch
$ngens = Get-ChildItem -Path "$env:windir\Microsoft.Net" -Filter ngen.exe -Recurse;foreach($ngen in $ngens){& "$($ngen.Directory)\$($ngen)" executeQueuedItems}
# Shorter version by Keith Garner
Get-ChildItem "$env:SystemRoot\Microsoft.net\NGen.exe" -recurse | %{ & $_ executeQueuedItems }

Great tip, thanks.
Thanks so much for this. I ran this script
Get-ChildItem "$env:SystemRoot\Microsoft.net\NGen.exe" -recurse | %{ & $_ executeQueuedItems }
And I get lots of errors like this could not load file or assembly Also compiling errors that seemed to be successful. Not sure if I need to be concerned about the other items. There are zillions of messages that I will try to capture to file when it finishes.
Hi Jeff, you can usually disregard from those compiling errors. Ngen will compile what it can.
/ Johan
Thanks so much Johan. Truly appreciated.
Shorter PowerShell:
Get-ChildItem $env:SystemRootMicrosoft.netNGen.exe -recurse | %{ & $_ executeQueuedItems }
Shorter NT Shell:
for /r %SystemRoot%Microsoft.NET %%i in ( ngen.exe ) do @if exist "%%i" "%%i" executeQueuedItems
Hi Arjan,
Awesome, thanks!
/ Johan
$ngens = Get-ChildItem -Path $env:windirMicrosoft.Net -Filter ngen.exe -Recurse;foreach($ngen in $ngens){& "$($ngen.Directory)$($ngen)" executeQueuedItems}
Great tip, thanks. I just need to write a PowerShell script for it, I'm allergic to batch files 🙂
/ Johan
Great post Johan, I've been irritated by this issue for quite a while and so much so that I've added a variant of this into my deployment task sequences. Each version of .Net has it's own optimization routine, so rather than build logic around determining which versions are installed, I do a search:
for /f "tokens=*" %%F in ('dir /b /s "%windir%Microsoft.net*ngen.exe"') do (
"%%F" executeQueuedItems
)
del /s /q /f "%windir%Microsoft.NET*.log"
This will search for all installed .Net ngen.exe files and run any pending optimizations (.net 2.0 and later)