1

I was debugging why a powershell script started failing and it looked like it was using Hashset without referencing the System.Core assembly, so the fix is to end up with something like this:

Add-Type -AssemblyName System.Core
$hash = new-object 'System.Collections.Generic.HashSet[string]'

What I can't figure out is how it was working before, and still runs just fine on some machines, without the add-type line. What am I missing here?

7
  • 1
    Check $profile to see if it's loading that assembly on those machines? Commented Dec 3, 2014 at 1:50
  • Different PowerShell versions? Commented Dec 3, 2014 at 10:41
  • @NathanTuggy I double checked, there is no profile file on either machine. Commented Dec 3, 2014 at 20:50
  • @ojk same powershell version on both machines. Commented Dec 3, 2014 at 20:51
  • My guess is that assembly was previously loaded by another application on your other machine. Try [appdomain]::currentdomain.GetAssemblies() on both and see if System.Core is loaded. Commented Dec 5, 2014 at 10:09

1 Answer 1

2
+200

To continue from David's thought, and because code in comments is horrid, you should check to see if the assembly is loaded. A small blog about checking assemblies is here

If (!(([appdomain]::currentdomain.GetAssemblies()).FullName -match "System\.Core")){
    Add-Type -AssemblyName System.Core
}
$hash = new-object 'System.Collections.Generic.HashSet[string]'

I have this assembly loaded by default. Curious what the affected systems have. What is the Dot.Net framework versions on affected machines? I had some of my 3.5 code stop working after Windows updates and need to reinstall framework.

Comment from Jeroen Mostert

If you want to be really precise about it, you should verify you've got .NET's very own System.Core, not any old impostor, and then there is no need to check that's already happened. Add-Type -AssemblyName "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

Sign up to request clarification or add additional context in comments.

5 Comments

Well if you want to be really precise about it, you should verify you've got .NET's very own System.Core, not any old impostor, and then there is no need to check that's already happened. Add-Type -AssemblyName "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" on its own is enough (version policies will take care of loading a later version if necessary).
@JeroenMostert good plan. Mine looks like this System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 not sure which one the op needs. Thanks. I'm still not sure if I should just delete this or not.
Because HashSet exists in 3.5, I'd go with that to maximize the chance of the script running. Unless you specifically need .NET 4.0, of course, but then that won't be because of HashSet.
The issue is going to be that if the default environment already has System.Core, Version=4.0.0.0, ... loaded -- and that assembly should load automatically if you have PowerShell 4.0, AFAIK -- then Add-Type will fail: "The type name and namespace must be unique within a session. You cannot unload a type or change it. If you need to change the code for a type, you must change the name or start a new Windows PowerShell session. Otherwise, the command fails." (See -Name parameter)
@BaconBits: except that's not true. I tried it on my own system, and Add-Type does not fail at all when attempting to load version 3.5 of System.Core is version 4.0 is already loaded (Powershell 3.0). This makes sense, since asking for 3.5 on .NET 4.0 will just get you 4.0, courtesy of versioning policy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.