Reputation: 1768
I am trying to change the location of the ASP.NET temporary files so that I can clean them up during the release of a new version.
Because it is very hard to find the location of the ASP.NET temporary files for a specific website, application of virtual directory under the C:\Windows\Microsoft.NET\Framework
C:\Windows\Microsoft.NET\Framework64
locations I decided it would be easier just to move the files to a specific location on the disk which can then be cleaned.
You can do this by modifying the tempDirectory attribute in the system.web/compilation
configuration section.
We have our server build and release processes automated therefore this looked straightforward to add the code to the configuration and release scripts.
However during testing I found that the location of 32-bit applications does not change.
The code I am using is:
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT' -location 'MyWebSite' -filter 'system.web/compilation' -name 'tempDirectory' -value 'E:\Temporary ASP.NET Files\MyWebSite' -Clr v2.0
This code works without errors and writes an entry into the root web.config file at: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\web.config
.
e.g.
<location path="MyWebSite">
<system.web>
<compilation tempDirectory="E:\Temporary ASP.NET Files\MyWebSite" />
</system.web>
</location>
Note that without the -Clr v2.0 parameter, the value would be written to the CLR 4.0 configuration file at C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
.
You can see the entry in IIS Configuration Editor as well:
The problem is the application pool is set to "Enable 32-Bit Applications" and therefore this property is ignored.
If I manually move the location element shown above from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\web.config
to C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config
The change works and indeed the ASP.NET temporary files move to this location specified when the compilation of the website occurs.
The question is not about ASP.NET temporary files, it is a more general question on how are you meant to configure 32-bit applications in PowerShell or indeed in IIS? There seems to be no way to do it which I find incredible. There are plenty of 32-bit applications around which still need to be configured.
Also please note that I have chosen to use the root web.config to store this value for good reasons:
ApplicationHost.config
cannot store system.web
configurationweb.config
file for the application itself.Upvotes: 0
Views: 3534
Reputation: 1768
After experimentation, using some information from the answer provided here and an offline conversation I can say conclusively that it is not possible to edit 32-bit root web.config files using the Microsoft WebAdministration PowerShell cmdlets.
It seems that the cmdlets are hard coded to only look at the 64-bit versions of the configuration files. IIS Manager behaves the same way. Why this is the case is inexplicable to me.
I also found a lot of problems using some of the cmdlets for editing 64 bit Clr 2.0 websites and applications. The Clr parameter is not present on all the cmdlets and even in the ones where it is it does not seem to always work.
Therefore I decided to abandon the WebAdministration cmdlets and use the 'Microsoft.Web.Administration.dll' assembly and the Microsoft.Web.Administration.ServerManager object directly.
The following are some of the functions I wrote which might be helpful:
function Get-MWAConfigObjects
{
<#
.SYNOPSIS
Returns object to manage IIS configuration in root web.config
.DESCRIPTION
The objects returned allow viewing or editing or configuration. Parameters open the appropriate version, either 32 or 64 bit for the appropriate version of the ManagedRunTime. https://msdn.microsoft.com/en-us/library/microsoft.web.administration.servermanager(v=vs.90).aspx
Ensure that you call CommitChanges to save any changes made.
.EXAMPLE
$MWA = Get-MWAConfigObjects -ManagedRunTimeVersion v2.0 -Architecture 32 $MWA.Configuration.GetSection('system.web/compilation','MyWebSite/MyApplication').SetAttributeValue('tempDirectory', 'C:\NewPath')
$MWA.ServerManager.CommitChanges()
#>
[cmdletbinding(positionalbinding = $false)]
param(
[Parameter(Mandatory = $True)][string][ValidateSet('v2.0','v4.0')] $ManagedRunTimeVersion,
[Parameter(Mandatory = $True)][string][ValidateSet(32,64)] $Architecture
)
$assemblyPath = $(Join-Path -Path $([System.Environment]::GetFolderPath('System')) -ChildPath $(Join-Path -Path 'inetsrv' -ChildPath 'Microsoft.Web.Administration.dll'))
If (Test-Path -Path $assemblyPath -PathType Leaf)
{
$null = [System.Reflection.Assembly]::LoadFrom($assemblyPath)
$iis = New-Object -TypeName Microsoft.Web.Administration.ServerManager
$wcm = New-Object -TypeName Microsoft.Web.Administration.WebConfigurationMap -ArgumentList $(Get-ConfigFilePath -Type machine -ManagedRunTimeVersion $ManagedRunTimeVersion -Architecture $Architecture), $(Get-ConfigFilePath -Type web -ManagedRunTimeVersion $ManagedRunTimeVersion -Architecture $Architecture)
$configuration = $iis.GetWebConfiguration($wcm, $null)
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name ServerManager -Value $iis
$object | Add-Member -MemberType NoteProperty -Name Configuration -Value $configuration
Write-Output -InputObject $object
}
else
{
Throw "Cannot validate existence of required assembly 'Microsoft.Web.Administration.dll' at ""$assemblyPath"""
}
}
function Get-ConfigFilePath
{
[CmdletBinding(PositionalBinding = $false)]
param
(
[Parameter(Mandatory = $True)][string][ValidateSet('web','machine')] $Type,
[Parameter(Mandatory = $True)][string][ValidateSet('v2.0','v4.0')] $ManagedRunTimeVersion,
[Parameter(Mandatory = $True)][string][ValidateSet(32,64)] $Architecture
)
$ErrorActionPreference = 'stop'
switch ($ManagedRunTimeVersion)
{
'v2.0'
{
switch ($Architecture)
{
32
{
$path = $(Join-Path -Path $([System.Environment]::GetFolderPath('Windows')) -ChildPath "Microsoft.NET\Framework\v2.0.50727\CONFIG\$Type.config")
break
}
64
{
$path = $(Join-Path -Path $([System.Environment]::GetFolderPath('Windows')) -ChildPath "Microsoft.NET\Framework64\v2.0.50727\CONFIG\$Type.config")
break
}
}
break;
}
'v4.0'
{
switch ($Architecture)
{
32
{
$path = $(Join-Path -Path $([System.Environment]::GetFolderPath('Windows')) -ChildPath "Microsoft.NET\Framework\v4.0.30319\CONFIG\$Type.config")
break
}
64
{
$path = $(Join-Path -Path $([System.Environment]::GetFolderPath('Windows')) -ChildPath "Microsoft.NET\Framework64\v4.0.30319\CONFIG\$Type.config")
break
}
}
break;
}
}
If (Test-Path -Path $path -PathType Leaf)
{
Write-Output -InputObject $path
}
else
{
Throw "Cannot validate configuration file at path ""$path"""
}
}
Upvotes: 0
Reputation: 116
there are two workarounds.
%windir%\syswow64\cmd.exe %windir%\syswow64\inetsrv\appcmd.exe set config -section:appSettings /+"[key='test',value='test']" /commit:webroot /clr:4.0
$iis = new-object Microsoft.Web.Administration.ServerManager $wcm = New-Object -TypeName Microsoft.Web.Administration.WebConfigurationMap -ArgumentList "C:\Windows\Microsoft.NET\Framework\v4.0.30319\CONFIG\machine.config","C:\Windows\Microsoft.NET\Framework\v4.0.30319\CONFIG\web.config" $iis.GetWebConfiguration($wcm, $null).GetSection("appSettings").SetAttributeValue("file", "test3") $iis.CommitChanges()
Upvotes: 1