Как настроить 32-разрядные веб-сайты или приложения IIS с помощью командлетов PowerShell
Я пытаюсь изменить расположение временных файлов ASP.NET, чтобы я мог их очистить при выпуске новой версии.
Поскольку очень трудно найти расположение временных файлов ASP.NET для конкретного веб-сайта, приложение виртуального каталога под C:\Windows\Microsoft.NET\Framework
C:\Windows\Microsoft.NET\Framework64
я решил, что будет проще просто переместить файлы в определенное место на диске, которое затем можно будет почистить.
Вы можете сделать это, изменив атрибут tempDirectory в system.web/compilation
раздел конфигурации.
Мы автоматизировали процессы сборки и выпуска нашего сервера, поэтому было просто добавить код в сценарии конфигурации и выпуска.
Однако во время тестирования я обнаружил, что расположение 32-битных приложений не меняется.
Код, который я использую:
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT' -location 'MyWebSite' -filter 'system.web/compilation' -name 'tempDirectory' -value 'E:\Temporary ASP.NET Files\MyWebSite' -Clr v2.0
Этот код работает без ошибок и записывает запись в корневой файл web.config по адресу: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\web.config
,
например
<location path="MyWebSite">
<system.web>
<compilation tempDirectory="E:\Temporary ASP.NET Files\MyWebSite" />
</system.web>
</location>
Обратите внимание, что без параметра -Clr v2.0 значение будет записано в файл конфигурации CLR 4.0 по адресу C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
,
Вы также можете увидеть запись в Редакторе конфигурации IIS:
Проблема заключается в том, что для пула приложений установлено значение "Включить 32-разрядные приложения", и поэтому это свойство игнорируется.
Если я вручную переместить элемент местоположения, показанный выше из C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\web.config
в C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config
Изменение работает, и действительно временные файлы ASP.NET перемещаются в это местоположение, указанное при компиляции веб-сайта.
Вопрос не в временных файлах ASP.NET, а в более общем вопросе о том, как вы собираетесь настраивать 32-разрядные приложения в PowerShell или даже в IIS? Кажется, нет никакого способа сделать это, что я считаю невероятным. Существует множество 32-битных приложений, которые еще нужно настроить.
Также обратите внимание, что я решил использовать корневой web.config для хранения этого значения по уважительным причинам:
ApplicationHost.config
не может хранитьsystem.web
конфигурация- Расположение временных файлов не является тем, что известно во время разработки и определяется конфигурацией хост-сервера. Поэтому этот параметр не может быть указан в
web.config
файл для самого приложения.
Спасибо за просвещение по этому вопросу.
2 ответа
Есть два обходных пути.
- Используйте 32-битный appcmd.exe. Вот пример.
% windir% \ syswow64 \ cmd.exe% windir% \ syswow64 \ inetsrv \ appcmd.exe set config -section: appSettings / + "[key = 'test', value = 'test']" / commit: webroot / clr: 4,0
- Используйте MWA непосредственно на powershell. Вот пример.
$ iis = новый-объект 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()
После экспериментов, используя некоторую информацию из ответа, предоставленного здесь, и офлайн-разговор, я могу окончательно сказать, что невозможно редактировать 32-битные корневые файлы web.config с помощью командлетов Microsoft WebAdministration PowerShell.
Кажется, что командлеты жестко запрограммированы, чтобы смотреть только на 64-битные версии файлов конфигурации. IIS Manager ведет себя так же. Почему это так необъяснимо для меня.
Я также обнаружил много проблем с использованием некоторых командлетов для редактирования 64-битных веб-сайтов и приложений Clr 2.0. Параметр Clr присутствует не во всех командлетах и даже в тех, где он есть, он не всегда работает.
Поэтому я решил отказаться от командлетов WebAdministration и использовать сборку "Microsoft.Web.Administration.dll" и объект Microsoft.Web.Administration.ServerManager напрямую.
Ниже приведены некоторые из написанных мной функций, которые могут оказаться полезными:
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"""
}
}
Я надеюсь, что это помогает кому-то.