Get-Website cmdlet causes an error

Hi Paul,

During deployment I’m using the Get-Website cmdlet to work out whether the site has been created in IIS already or not. However, every time the tentacle runs the script I get this error:

ERROR: Get-Website : Could not load file or assembly ‘System.Security’ or one of its d
ERROR: ependencies. The system cannot find the file specified.

I’ve got the following at the top of my script, and if I run it manually everything works fine, it seems only to be an issue when run from the tentacle:

Set-ExecutionPolicy Unrestricted
Import-Module WebAdministration
[Reflection.Assembly]::LoadWithPartialName(“System.Security”)

I’m deploying to Win2008R2 Standard x64. Any ideas what the problem might be - is there something I should add to my PS or is it a Tentacle issue? The Tentacle is running as a domain user with admin rights.

Thanks,
John

Hi John,

I run the PowerShell script within a custom PowerShell host, so there might be something I need to do to support assembly resolution. I’ll try your script and aim to get a new build out with a fix tonight.

Paul

Awesome, thanks Paul.

Hi John,

I think I know what’s going on here. Octopus runs as a .NET Framework 4.0 process. However when you run PowerShell 2.0 from Windows, it actually runs under a .NET 2.0 runtime.

In PowerShell, when the LoadWithPartialName line runs, I get this output:

GAC    Version        Location
---    -------        --------
True   v2.0.50727     C:\Windows\assembly\GAC_MSIL\System.Security...

However, when I run the same line within Tentacle, I get:

GAC    Version        Location
---    -------        --------
True   v4.0.30319     C:\Windows\assembly\GAC_MSIL\System.Security....

When the script then runs Get-Website, it needs to resolve the .NET 2.0 version of System.Security, but the .NET 4.0 version is loaded into Tentacle - and only one version of an assembly can be loaded at once. That’s why you receive that error.

When I run the script in Tentacle, it appears the Assembly.Load… line isn’t actually needed - calling Import-Module followed by Get-Websites works for me. However if you do need to force load the assembly, you can do it by specifying the version:

[Reflection.Assembly]::Load("System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")

Hope this helps, and thanks very much for reporting the problem!

Paul

Hi Paul,

Thanks for that info, but unfortunately this doesn’t appear to work for me. When I add the Assembly.Load Tentacle still outputs v4.0.30319, which seems odd? I’ve also tried moving where I load this, and where I do the Import-Module but continue to get the same issue. Any further ideas I could try? I’m on v0.8.398.2027.

Thanks,
John

Hi Paul,

This is becoming a real issue for us now, do you have any further suggestions I could try?

Thanks,
John

Hi John,

I’m sorry, I lost track of this discussion. I will look into this again tonight and try and work out what is going on.

Last time I tried, I also got ‘4.0.30319’ in the output, but a call to Get-Website succeeded. I’ll test it again on some other machines.

I will get back to you with an update in the next 5 hours.

Paul

Hi John,

I spent a lot of time tonight trying to reproduce this issue, but I am unable to. Version 4.0.30319 is loaded, but I can still call Get-Website without problems. I’ve tried this on Windows 7 x64, Windows Server 2008 R2 x64, and Windows Server 2008 R1 x32, running under a mix of local user (as admin) and Local System accounts.

Are you able to tell me:

  1. The account your Tentacle service is running as (by default it is Local System)
  2. The error message you get when you call Get-Website after Assembly.Load
  3. The error message you get if you do not call Assembly.Load

A full copy of the script would be very valuable.

Can you also remote into the machine running Tentacle, and send me the output of this command?

Get-Module -ListAvailable

And this command:

Get-PSSnapin

Thanks,

Paul

(Sorry, didn’t mean to click Close)

Hi Paul,

Attached are my scripts and the output from the given commands. I was running the Tentacle as a domain user who is a member of the domain admin group, I’ve since tried it with Local System and got more or less the same results (errors I got were because Local System didn’t have permission to access the SAN, but that was expected behaviour).

The error I get from PS when hitting Get-Website is “Could not load file or assembly ‘System.Security’ or one of its dependencies. The system cannot find the file specified.”, and I get this whether or not I do the Assembly.Load.

The domains’ admin group is a member of the local machines Administrators group.

Thanks,
John

Deploy.zip (5 KB)

Hi Paul,

I can now see what’s happening here, but not quite sure how to get around it (yet!). It would seem that if I use Get-Website in the predeploy.ps1 file itself it works perfectly - however, when it’s called it in a dot sourced include (as I am) this fails!

Thanks,
John

Hi John,

Thanks very much for the information - that will go a long way to helping me solve this one. I’ll spend some time on it tonight and let you know ASAP!

Paul

Hi Paul,

Did you manage to make any progress on this?

Thanks,
John

Hi John,

I’m sorry, I haven’t had a chance to look at this yet. It’s the first thing I’ll be looking at when I get back to my laptop tonight.

Paul

Hi John,

Can I get you to try making one change to your Tentacle.exe.config file, by adding the useLegacyV2RuntimeActivationPolicy attribute:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">

After restarting the Tentacle service, re-deploy your package, and let me know how it goes. Since WebAdministration uses System.Security v2, I believe this setting will make it accept v4 as an acceptable version.

I’m still unable to reproduce this issue locally but if this doesn’t solve it I will set up a test package using your scripts as-is on a fresh Server 2008 R2 machine to see how I go.

Paul

Hi John,

Also, could you see what happens if you try running your scripts using this:

PoshConsole will host PowerShell in .NET 4.0 in very much the same way I do.

Paul

Hi Paul,

I tried your ideas with the config but with no success - basically the same results as before. PoshConsole gave this exception with Get-Website:

Get-Website : Object reference not set to an instance of an object.
At line:1 char:21

  • $sites = Get-WebSite <<<<
    • CategoryInfo : NotSpecified: (:slight_smile: [Get-Website], NullReferenceException
    • FullyQualifiedErrorId : System.NullReferenceException,Microsoft.IIs.PowerShell.Provider.GetWebs
      iteCommand

I’ve worked around my issue by moving the get-website in to the parent script, so deployments are currently working. This is not the end of the world at the moment so perhaps can be marked for later investigation, but it would definitely seem to be related to the dot include mechanism.

FYI, a colleague has pointed me at an alternative way of doing get-website because of a WOW64 issue, and this DOES work in PoshConsole, I’ve not had chance to try it in my script yet though:

[System.Reflection.Assembly]::LoadFrom( “C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll” ) | out-null
$iis = new-object Microsoft.Web.Administration.ServerManager

Thanks,
John

Hi John,

Glad you worked around it. I’d be curious to know whether the new approach works in Octopus too. Sorry I’ve been unable to reproduce this one - I’m going to put some thought into finding ways to reproduce stuff like this more reliably. There may be some differences in our OS/script configurations that I’m just not aware of.

Paul

We were having the same issue with a deployment to a machine running PS v4 and .NET 4.5.1. Upgrading to .NET 4.5.2 resolved it.