PowerShell IIS Set-WebConfigurationProperty - Locked ApplicationHost.config section - powershell

I am writing a PowerShell 3.0 installer for our web applications and web services and am getting tripped up when attempting to set physical path credentials.
My code looks like this:
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# >>>>>> Path credentials
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# Set the physical path credentials of the web application (on Basic Settings screen) to Connect As...
$filter="/system.applicationHost/sites/site[#name='{0}' and #id='1']/application[#path='/{1}']/VirtualDirectory[#path='/']" -f $script:WebSiteName,$appName
Set-WebConfiguration $filter -Value #{userName="$physicalPathCredentialUserID";password="$physicalPathCredentialPassword"}
When executing, I get an error in PowerShell stating "This configuration section cannot be used at this path. This happens when the section is locked at a parent level". I tried the PSPath and location tags that work when Authentication sections are locked, but those don't seem to have any effect. I thought maybe the -Force option would work, but although no error was thrown, the physical path credentials didn't seem to take.
Without the -Force option, the error is thrown but PowerShell cuts off the message so I can't tell exactly what section it is complaining about, or what parent level is locked. I have to assume it is the Sites section since I am attempting to configure: /configuration/system.applicationHost/sites/application/virtualDirectory
I'm a bit confused about the difference between unlocking and allowing override to get the values to stick. PowerShell WebAdministration is pretty confusing in this area. I don't know why it has to be so confusing to set the values that are corollaries to what can be set in the IIS adminstration UI. Some values use Set-WebConfiguration with an ugly string as shown above, others use Set-WebConfigurationProperty. If locking is a known issue, why isn't unlocking better documented?
I don't want to unlock all sites or all applications. I just want to unlock what I have to in order to set the configuration values on each web application I am installing under Default Web Site.
What is the definitive solution to unlocking or overriding configuration sections as of 2014 and PowerShell 3.0? And which settings accept PSPath and location?
By the way, I have tried variants of the following:
$filter="/system.applicationHost/sites/site[#name='{0}' and #id='1']/application[#path='/{1}']/VirtualDirectory[#path='/']" -f $script:WebSiteName,$appName
Set-WebConfiguration $filter machine/webroot/appHost -metadata overrideMode -value Allow
but continued to get the locked section message until the filter was backed off to the sites level.
I also tried setting the virtualDirectoryDefaults.userName and virtualDirectoryDefaults.password, which didn't seem to take initially, but after an IISReset I noticed they were indeed added at the bottom of the applicationHost.config file. I don't really want them set as defaults because our apps shouldn't affect other apps on the server.
I appreciate any assistance you can provide. I must be missing something because it shouldn't be so difficult to set these and other web application configuration values.
Regards

The sections you are trying to change are set in the IIS machine config. You have to unlock the sections in order to set them per-site.
See: Programmatically unlocking IIS configuration sections in Powershell

Your Filter does not look right. You can think of the filter as basically an XPath query. So if you use a filter of //authentication/* then that will get all of your configuration under an authentication node. It's not exactly the same as XPath, but it's pretty close. Just remember that you can't select metadata sections like sectionGroup or location tags using just the Filter parameter alone.
I had an issue where I needed to have Windows authentication unlocked at the server level that way I could set Windows auth to different values at the application level. So I had to do something like this:
Set-WebConfiguration -Metadata OverrideMode -Value Allow -Filter //windowsAuthentication
Set-WebConfigurationProperty -PSPath IIS:\Sites\$WebsiteName\$AppName -Filter //windowsAuthentication -Name Enabled -Value $true
What this did was create a section in the applicationHost.config file that looked like this:
<location path="" overrideMode="Allow">
<system.webServer>
<security>
<authentication>
<windowsAuthentication>
</windowsAuthentication>
</authentication>
</security>
</system.webServer>
</location>
Whatever configuration you place with that location tag will be considered unlocked according to IIS I believe.
And this is what was added to the Web.config file in the web application itself:
<authentication>
<windowsAuthentication enabled="true" />
</authentication>
Hopefully this helps.

Related

PowerShell - Accessing root web.config

I can't seem to find a good hint on accessing the root web.config, currently in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config. In my situation, I want to apply a few security settings to cascade down to apps (ex: disable sessionstate/compression) where ideally I'd do this in PowerShell DSC using xWebConfigProperty, or possibly raw PowerShell. If anyone has a means to retrieve this (have to use the older WebAdministration module), I'd appreciate it (or just verifying I need something more organic like gci path into xml for manipulation).
Changes applied to root web.config using 'MACHINE/WEBROOT'.
You can test with something like:
Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT' -name "mode" -filter "system.web/sessionState"

Running powershell without useriteraction

start "odopen://sync/?siteId=$siteid17&webId=$webid17&listId=$listid17&userEmail=$upn&webUrl=$URL17&webtitle=$webtitle17&listtitle=$listtitle17"
How is it possible to run the following command inside Powershell without an appearing popup window or any userinteraction? I've tried adding /ArgumentList "/S", "/Background". Also tried with -WindowStyle Hidden at the end. Appreciate some help :)
Your command as-is basically says "Start the program that opens odopen:// (OneDrive) links" and can't really be given any silent style instructions. The proper way to configure this kind of thing is through OneDrive Group Policies, but we can cheat and set registry keys.
The link above goes into detail about how to configure group policy, but also tells us that the specific group policy setting to "Configure team site libraries to sync automatically" sets this registry key:
[HKCU\Software\Policies\Microsoft\OneDrive\TenantAutoMount]"LibraryName"="LibraryID"
And that your LibraryID is in this format, which looks familiar:
tenantId=xxx&siteId=xxx&webId=xxx&listId=xxx&webUrl=httpsxxx&version=1
So to put it in a script, I would use something like this, adapted from Nicola Suter's blog post here:
$tenantAutoMountRegKey = "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive\TenantAutoMount"
$autoMountTeamSitesList= #{
#Enter your SharePoint libraries to configure here as key/value pairs
MySharePoint="odopen://sync/?siteId=$siteid17&webId=$webid17&listId=$listid17&userEmail=$upn&webUrl=$URL17&webtitle=$webtitle17&listtitle=$listtitle17"
}
# Check if the key exists and create if missing:
if (-not (Test-Path $tenantAutoMountRegKey)){ New-Item -Path $tenantAutoMountRegKey -Force }
# Add the sites for automatic mounting
$autoMountTeamSitesList | Set-ItemProperty -Path $tenantAutoMountRegKey -Name $_.Key -Value $_.Value
This generally takes effect the next time a user signs into OneDrive, though Microsoft warns it may take up to 8 hours to start syncing (Keeps hundreds of users from syncing the same library at the same time)
TL;DR: You cannot.
Using odopen will always show sign-in window (as stated here: https://learn.microsoft.com/en-us/onedrive/deploy-on-windows#help-users-sign-in), what you can do is only populate it with data, which is what you are already doing.
If you want to do it silently, there is documentation about it: https://learn.microsoft.com/en-us/onedrive/use-silent-account-configuration

How to use DSC to confgure httpErrors defaultPath

In a DSC configuration script for IIS, I am trying to remove the defaultPath lock from the httpErrors section but the way in which the feature delegation works does not apply to this section. Hence to do the following:
appcmd set config /section:httpErrors /lockAttributes:
I've tried using the xWebConfigProperty as follows:
xWebConfigProperty httpErrors_lockAttributes
{
WebsitePath = "MACHINE/WEBROOT/APPHOST"
Filter = "system.webServer/httpErrors"
PropertyName = "lockAttributes"
Value = ""
Ensure = "Absent"
}
However this fails with an error saying the lockAttributes attributes does not exist. And yet it is definitely in the ApplicationHost.config
My only remaining workaround is to run the appcmd as Script in the DSC (a little ugly). Any ideas?
You could use below PowerShell command to remove lock from the default path:
Remove-WebConfigurationLock -pspath 'MACHINE/WEBROOT/APPHOST' -filter "system.webServer/httpErrors/#defaultPath"
I know this is old as all heck. But what I've found is a lot of these modules and resources were built for specific tasks and are less modular than other DSC tools. You may have to create a custom resource that handles Remove-WebConfigurationLock in its set/get/test functions if you want a "pure" DSC solution. If not, a DSC script resource will do what you need.

Difference between WebCommitDelay and IISCommitDelay

What is the difference between WebCommitDelay and IISCommitDelay?
MS docs says the same for both:
Instructs the IIS configuration system to delay the commitment of changes.
So what should I prefer and why? It looks like they have some differences indeed, because if I use WebCommitDelay, I can't use New-WebApplication ... -Force if the same application is exists, but I can do this if I use IISCommitDelay.
As far as I know, the IISAdministration PowerShell module which was a new way to manage IIS.
This module included numerous improvements over the existing WebAdministration cmdlets.
So the IISCommitDelay is the new method which is used to management the IIS.
Detials, you could refer to this article.

Why appcmd.exe does not allow to set ipSecurity allowUnlisted?

I would like to set ip restriction to the /admin folder on my website with PowerShell.
I do understand, that because this section is locked I have to go to applicationHost.config, and unless I unlock I can not use local web.config in that particular folder.
I also figured out how can I add an IP restriction rule using appcmd.exe.
Because of allowUnlisted is true (Allow) by default, I also have to set it false, which I can not accomplish, because when I use the following command I got error:
$location = "My Site/admin"
appcmd.exe set config $location -section:system.webServer/security/ipSecurity /allowUnlisted:false
ERROR ( message:Can not set attribute "allowUnlisted" to value "false".. Reason: This configuration section cannot be used at this
path. This happens when the section is locked at a parent level.
I also discovered that there is appcmd lock/unlock facility, but those commands does not allow a specific location. I do not want to change anything expect my $locations behavior, and do this in applicationHost.config.
Which is completely possible using the GUI, in IIS Manager using the IP Restrictions on my particuar admin folder in Edit feature I can set it to Deny, and that adds to the end of applicationHost.config the following lines (no other changes):
<location path="My Site/admin">
<system.webServer>
<security>
<ipSecurity allowUnlisted="false">
<add ipAddress="127.0.0.1" allowed="true" />
</ipSecurity>
</security>
</system.webServer>
</location>
Question
How can I do this change in applicationHost.config with CLI way?
I don't know much about using appcmd.exe. However, if you want to use the powerShell WebAdministration module, then you can use the following:
$location = "My Site/Admin"
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location $location -filter "system.webServer/security/ipSecurity" -name "allowUnlisted" -value "False"
Add /commit:
.\appcmd.exe set config "Default Web Site" -section:system.webServer/security/ipSecurity /allowUnlisted:'false' /commit:apphost
If you want to do it using appcmd