locked
ServerManager to update ApplicationHost.con RRS feed

  • Question

  • User-504484440 posted

    More specifically, we're building an install program for a couple of websites.  We only support IIS 7.0 or higher and we're using Microsoft.Web.Administration.

    In order to implement AD pass through authentication we have to set Authentication properties on some individual files.

    The end result of doing this through IIS Manager is an entry in the ApplicationHost.Config file like this.

      <location path="Default Web Site/SmartLynxDataSvc/Trunk/SmartLynxWindowsCredential.svc">
        <system.webServer>
          <security>
            <authentication>
              <anonymousAuthentication enabled="false" />
              <windowsAuthentication enabled="true" />
            </authentication>
          </security>
        </system.webServer>
      </location>

    When I try to open a Location section, I get it's missing an element tag or such.

    What I plan on doing is using the GetLocalPaths to see if an entry exists.  If it doesn't I need to create a new Location Element.

    I'd prefer not to resort to open the file with and editing it directly in code and rather use ServerManager if there is a way.

     

    Thanks

     

    Thursday, April 4, 2013 4:06 PM

Answers

  • User-504484440 posted

    I had to resort to editing the applicationHost.config file manually as I've had no luck finding another way.

    However, on x64 systems, that has turned out to be another problem because you can't open the system32\inetsrv\applicationHost.config file.

    I found this link for creating a symbolic file link.

    http://troyparsons.com/blog/2012/03/symbolic-links-in-c-sharp/

    I then wrote this code to try and open the file and if it fails, create a symbolic link.

    try
                        {
                            // Only 
                            _maxLoops--;
    
                            _retVal = XElement.Load(GlobalSetupValues.IISConfig.ApplicationHostConfigPath);
                        }// If the file can't be find, then we have to setup a symbolic file path.  This is the case on x64 machines
                        catch (FileNotFoundException fex)
                        {
                            // Do nothing because we expect this on a x64 system
                            CommonHelpers.LogMessage(string.Format("Could not open {0}, will create a symbolic link and try again", GlobalSetupValues.IISConfig.ApplicationHostConfigPath), GlobalSetupValues.LogMessageTypes.Warning);                                 
    
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
    
                        // On a x64 system you have to set up a symbolic link of the or you will not be able to open the applicationHost.config
                        // Code to work with Symbolic links
                        // http://troyparsons.com/blog/2012/03/symbolic-links-in-c-sharp/
    
                        // This should only be null on a x64 system.  Otherwise IIS isn't installed or there are other problems
                        // Only try this one time or error out
                        // To go back to default, delete the config directory in the wow folder.  Make sure you have a copy of the files
                        // as you may need to put the config files back in the 32 bit config folder
                        if (_retVal == null && _maxLoops > 0)
                        {
                                // If this is the case, we'll have to create a symbolic link
                            StringBuilder _sbCmdText = new StringBuilder();
                            // Direct the command to run and terminate without user input
                            // If you need for the window to stay open
                            //_sbCmdText.Append("/k ");
                            _sbCmdText.Append("/c ");
                            _sbCmdText.Append("cd /d \"%systemdrive%\\windows\\syswow64\\inetsrv\"");
                            _sbCmdText.Append(" & move config configx86 ");
                            _sbCmdText.Append(" & MKLINK /d Config \"%systemdrive%\\windows\\system32\\inetsrv\\config\"");
    
                            System.Diagnostics.Process _process = new Process();
                            System.Diagnostics.ProcessStartInfo _processStartInfo = new ProcessStartInfo();
                            _processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                            _processStartInfo.FileName = "cmd.exe";
                            _processStartInfo.Arguments = _sbCmdText.ToString();
                            _processStartInfo.UseShellExecute = false;
                            _process.StartInfo = _processStartInfo;
    
                            _process.Start();
                            // Must wait for the cmd to finish
                            _process.WaitForExit();
    
                        }

    THen this code to set location path I need on the file that needs direct settings.

    var _locationPathElement = _applicationHostElement.Descendants("location").Where(w => w.Attribute("path").Value == locationPath).SingleOrDefault();
    
                            const string ANONYMOUSAUTHENTICATION = "anonymousAuthentication";
                            const string WINDOWSAUTHENTICATION = "windowsAuthentication";
    
                            // If the path exists, must check for the windowsAuthentication element and that it's value is true and anonymousAuthentication = false
                            // 
                            if (_locationPathElement != null)
                            {
                                //<location path="Default Web Site/SmartLynxDataSvc/Trunk/SmartLynxWindowsCredential.svc">
                                //    <system.webServer>
                                //      <security>
                                //        <authentication>
                                //          <anonymousAuthentication enabled="false" />
                                //          <windowsAuthentication enabled="true" />
                                //        </authentication>
                                //      </security>
                                //    </system.webServer>
                                //  </location>
    
                                bool _hasChanges = false;
    
                                // Make sure anonymousAuthentication is false and windowsAuthentication = true;
                                XElement _anonymousAuthentication = _locationPathElement.Descendants(ANONYMOUSAUTHENTICATION).SingleOrDefault();
    
                                if (_anonymousAuthentication == null)
                                {
                                    _anonymousAuthentication = new XElement(ANONYMOUSAUTHENTICATION, false);
                                    
                                }
                                else
                                {
                                    if (bool.Parse(_anonymousAuthentication.Attribute("enabled").Value) != false)
                                    {
                                        _anonymousAuthentication.Attribute("enabled").Value = "false";
                                        _hasChanges = true;
                                    }
                                }
    
                                XElement _windowsAuthentication = _locationPathElement.Descendants(WINDOWSAUTHENTICATION).SingleOrDefault();
    
                                if (_windowsAuthentication == null)
                                {
                                    _windowsAuthentication = new XElement(WINDOWSAUTHENTICATION, false);
                                    
                                }
                                else
                                {
                                    if (bool.Parse(_windowsAuthentication.Attribute("enabled").Value) != true)
                                    {
                                        _windowsAuthentication.Attribute("enabled").Value = "true";
                                        _hasChanges = true;
                                    }
                                }
    
                                if (_hasChanges)
                                {
                                    _applicationHostElement.Save(GlobalSetupValues.IISConfig.ApplicationHostConfigPath);
                                }
    
                            }
                            else
                            {
                                _locationPathElement = new XElement("location", new XAttribute("path", locationPath),
                                                                    new XElement("system.webServer",
                                                                    new XElement("security",
                                                                    new XElement("authentication",
                                                                    new XElement(ANONYMOUSAUTHENTICATION,
                                                                    new XAttribute("enabled", false)),
                                                                    new XElement(WINDOWSAUTHENTICATION, new XAttribute("enabled", true))))));
    
                                _applicationHostElement.Add(_locationPathElement);
    
                                _applicationHostElement.Save(GlobalSetupValues.IISConfig.ApplicationHostConfigPath);
    

    It would nice to make the call via ServerManager but I've yet to find a way to do so.

     

    • Marked as answer by Anonymous Tuesday, September 28, 2021 12:00 AM
    Tuesday, April 9, 2013 8:29 AM