<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/iis/</id>
  <link href="https://www.endpointdev.com/blog/tags/iis/"/>
  <link href="https://www.endpointdev.com/blog/tags/iis/" rel="self"/>
  <updated>2021-09-27T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Deploying a .NET 5 app on IIS</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2021/09/deploying-dotnet-5-app-iis/"/>
      <id>https://www.endpointdev.com/blog/2021/09/deploying-dotnet-5-app-iis/</id>
      <published>2021-09-27T00:00:00+00:00</published>
      <author>
        <name>Juan Pablo Ventoso</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2021/09/deploying-dotnet-5-app-iis/puzzle-cropped.jpg&#34; alt=&#34;Puzzle&#34;&gt;
&lt;a href=&#34;https://flic.kr/p/4riBj8&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/photos/nexus_icon/&#34;&gt;Christian Cable&lt;/a&gt;, CC BY 2.0&lt;/p&gt;
&lt;p&gt;.NET 5 has been around for a few years now, after being &lt;a href=&#34;/blog/2020/11/dotnet-5-released-net-conf-2020/&#34;&gt;released at .NET Conf 2020&lt;/a&gt;, containing the best of both worlds: .NET Core, including multi-platform support and several performance improvements, and .NET Framework, including Windows desktop development support with WPF and Windows Forms (UWP is also supported, but not officially yet).&lt;/p&gt;
&lt;p&gt;A .NET Core-based project can be published into any platform (as long as we’re not depending on libraries targeted to .NET Framework), allowing us to save costs by hosting on Linux servers and increasing performance by having cheaper scalability options. But most developers are still using Windows with Internet Information Services (IIS) as the publishing target, likely due to the almost 20 years of history of .NET Framework, compared to the relatively short history of .NET Core, launched in 2016.&lt;/p&gt;
&lt;h3 id=&#34;our-net-project&#34;&gt;Our .NET project&lt;/h3&gt;
&lt;p&gt;We won’t review the &lt;a href=&#34;/blog/2021/07/dotnet-5-web-api/&#34;&gt;steps needed to set up a new .NET 5 project&lt;/a&gt;, since this time we are only focusing on publishing what we already have developed. But to understand how our application will integrate with IIS and the framework, it’s important to note a fundamental change any .NET 5 project has in comparison with a .NET Framework one:&lt;/p&gt;
&lt;p&gt;Since .NET 5 is .NET Core in its foundation, our project output will actually be a console application. If we create a new .NET Core project, no matter which version we are using, we will find a &lt;code&gt;Program.cs&lt;/code&gt; file in the root with an application entry point in it, that will look somewhat similar to the one below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c#&#34; data-lang=&#34;c#&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;Program&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; Main(&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		BuildWebHost(args).Run();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;static&lt;/span&gt; IWebHost BuildWebHost(&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;string&lt;/span&gt;[] args) =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		WebHost.CreateDefaultBuilder(args)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			.UseStartup&amp;lt;Startup&amp;gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			.Build();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;a href=&#34;https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-5.0&#34;&gt;&lt;code&gt;WebHost&lt;/code&gt;&lt;/a&gt; object will be the one processing requests to the app, as well as setting configuration like the content root, accessing environment variables, and logging.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This application needs to be executed by the &lt;code&gt;dotnet&lt;/code&gt; process, which comes with any .NET 5 runtime.&lt;/p&gt;
&lt;h3 id=&#34;installing-a-net-5-runtime&#34;&gt;Installing a .NET 5 runtime&lt;/h3&gt;
&lt;p&gt;The first step we need to do in our destination server, is to prepare the environment to run .NET 5 apps by installing the &lt;a href=&#34;https://dotnet.microsoft.com/download/dotnet/5.0&#34;&gt;.NET 5 Hosting Bundle&lt;/a&gt;, a 65 MB setup file which has all the basic stuff needed to run .NET 5 on Windows. Since .NET can also run on Linux and macOS, installer executables are available for these operating systems as well.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/09/deploying-dotnet-5-app-iis/dotnet-hosting-bundle-screenshot.jpg&#34; alt=&#34;Installing the hosting bundle&#34;&gt;&lt;/p&gt;
&lt;p&gt;Once the installation finishes, we will need to restart IIS by typing &lt;code&gt;iisreset&lt;/code&gt; on an elevated command prompt.&lt;/p&gt;
&lt;h3 id=&#34;creating-the-application-pool&#34;&gt;Creating the application pool&lt;/h3&gt;
&lt;p&gt;It’s always recommended to create a new application pool for a new website that will be published. That allows us to run the website in a separate IIS process, which is safer and prevents other websites from crashing if an application throws an unhandled exception. To create a new application pool, right-click on the “Application pools” section on the IIS Manager sidebar and choose the option “Add application pool”.&lt;/p&gt;
&lt;p&gt;Since .NET 5 is based on .NET Core, the application pool we create will not be loaded inside the &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/standard/clr&#34;&gt;.NET Framework runtime environment&lt;/a&gt;. All .NET 5 applications will run by calling the external &lt;code&gt;dotnet&lt;/code&gt; process, which is the reason why we need to install a separate hosting bundle in the first place.&lt;/p&gt;
&lt;p&gt;That means that, when we are creating our application pool, we will need to set the .NET CLR version to &amp;ldquo;No managed code&amp;rdquo; before saving changes, as shown below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/09/deploying-dotnet-5-app-iis/iis-new-app-pool.jpg&#34; alt=&#34;App pool settings&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;creating-the-new-website&#34;&gt;Creating the new website&lt;/h3&gt;
&lt;p&gt;With the bundle installed and a new application pool created, it’s time to add the new website where our application will be published to. Right-click on the “Sites” section on the IIS Manager sidebar and choose the “Add Website” option.&lt;/p&gt;
&lt;p&gt;We can choose any name to identify the new website. The important thing is to point the website to the newly created application pool, and bind it to the correct IP address and domain/​host name, as shown below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/09/deploying-dotnet-5-app-iis/iis-new-website.jpg&#34; alt=&#34;Setting up a new website&#34;&gt;&lt;/p&gt;
&lt;p&gt;Once we accept the changes, the new website will be automatically started, which means we should be able to reach the IP address/​hostname we entered. We will get a default page or a 404 response, depending on how our IIS instance is configured, since we haven’t published our application yet.&lt;/p&gt;
&lt;h3 id=&#34;publishing-our-project&#34;&gt;Publishing our project&lt;/h3&gt;
&lt;p&gt;Finally, it’s time to publish our .NET application into the new website. If we have Visual Studio, we can have the IDE automatically upload our content to IIS and publish it by right-clicking on our project and choosing &amp;ldquo;Publish&amp;rdquo;. Or we can use the &lt;code&gt;dotnet&lt;/code&gt; command with the &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish&#34;&gt;&lt;code&gt;publish&lt;/code&gt;&lt;/a&gt; parameter to do it ourselves.&lt;/p&gt;
&lt;p&gt;I usually prefer to do a manual publish into a local folder, and then decide which content I need to copy into the destination. Sometimes we only update a portion of the backend logic, in which case copying the output DLLs is all we need to do.&lt;/p&gt;
&lt;p&gt;If we choose to let Visual Studio handle the publishing process, we need to choose &amp;ldquo;Web Server (IIS) / Web deploy&amp;rdquo; as our publish destination and enter the information needed for Visual Studio to connect to the server and copy the files:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/09/deploying-dotnet-5-app-iis/visual-studio-publish-screen.jpg&#34; alt=&#34;Publishing the website&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We need to make sure that the &amp;ldquo;site name&amp;rdquo; we enter here corresponds to the site name we entered when we created the new website on the server.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;If you prefer to manually copy the files like me, on the destination screen choose &amp;ldquo;Folder&amp;rdquo; instead of &amp;ldquo;Web Server (IIS)&amp;rdquo;. That option will copy the project’s output into the specified folder, so it can be manually copied into our website’s root later.&lt;/p&gt;
&lt;p&gt;And that’s it! Our project is now published into the website we created. We can hit our IP address/​hostname again and we should now get our website’s default response.&lt;/p&gt;
&lt;p&gt;To sum it up, the main difference between publishing a .NET Framework app and a .NET 5 app is that we need to install a runtime and do a couple of tweaks when setting up the new application pool. But in general, it’s a pretty straightforward process.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Keeping our Windows Server clean</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2019/09/keeping-our-windows-server-clean/"/>
      <id>https://www.endpointdev.com/blog/2019/09/keeping-our-windows-server-clean/</id>
      <published>2019-09-27T00:00:00+00:00</published>
      <author>
        <name>Juan Pablo Ventoso</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2019/09/keeping-our-windows-server-clean/cover.jpg&#34; alt=&#34;Keeping our Windows Server clean&#34; /&gt; &lt;a href=&#34;https://flic.kr/p/ofjEj4&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/photos/oneilsh/&#34;&gt;Shawn O’Neil&lt;/a&gt;, used under &lt;a href=&#34;https://creativecommons.org/licenses/by/2.0/&#34;&gt;CC BY 2.0&lt;/a&gt;, cropped from original&lt;/p&gt;
&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I have been running websites and web applications under Windows Server for years, for both work and personal purposes. Most of them were small websites with a few daily visitors, but one particular case (a &lt;a href=&#34;https://www.pronosticoextendido.net&#34; target=&#34;_blank&#34;&gt;weather website&lt;/a&gt; I originally created as a hobby) grew over time to around one million page views per month.&lt;/p&gt;
&lt;p&gt;The website is mostly ASP.NET, with some services and components written in PHP and Python, and uses MySQL for persistence (as well as a bunch of XML/PNG files to cache weather forecasts and weather imagery). As months passed by, I’ve discovered that the default IIS and Windows log files will grow drastically so, while checking its content periodically to detect issues and vulnerabilities, we need to take action to preserve free disk space and server performance.&lt;/p&gt;
&lt;h3 id=&#34;internet-information-services-log-files&#34;&gt;Internet Information Services log files&lt;/h3&gt;
&lt;p&gt;In our IIS public folder (by default &lt;code&gt;C:\inetpub&lt;/code&gt;) we will have a path &lt;code&gt;logs\LogFiles&lt;/code&gt;. Inside that folder, the IIS service will create a set of folders, one per HTTP/FTP service that is running under our instance. How fast it will grow depends on many things, mainly traffic, but also website visibility and bad requests. But it will start to sooner or later consume our free disk space.&lt;/p&gt;
&lt;p&gt;To prevent this, we can create a batch file that can be run on a daily basis from a scheduled task.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CleanIISLogs.bat&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;forfiles /D -10 /P &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\inetpub\logs\LogFiles&amp;#34;&lt;/span&gt; /S /C &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;cmd /c del /f /q @path&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This script traverses through all files on the folder passed by parameter that are more than 10 days old, and for each file, it executes the &lt;code&gt;del&lt;/code&gt; command in quiet mode. This script will search for all files within the folder and all subfolders that are more than 10 days old and delete them. After running the task, we should confirm that the used space was reduced:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/09/keeping-our-windows-server-clean/logfiles-space-green-check.jpg&#34; alt=&#34;Folder properties after cleanup&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;http-error-logs&#34;&gt;HTTP Error logs&lt;/h3&gt;
&lt;p&gt;There is another location where different operating system logs are stored: &lt;code&gt;C:\Windows\System32\LogFiles&lt;/code&gt;. And when we navigate there, we will find an &lt;code&gt;HTTPERR&lt;/code&gt; folder which will also start consuming free space as our websites are visited. The log files in that folder will save information regarding HTTP errors from any API/Service running on our IIS instance.&lt;/p&gt;
&lt;p&gt;So depending on the web traffic our applications have, it will grow faster or slower. But in any case, I recommend creating a batch file to clean old log files using the &lt;code&gt;del&lt;/code&gt; command, and to run that file on a daily basis by configuring a scheduled task.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CleanHTTPERRLogs.bat&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;forfiles /D -10 /P &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\Windows\System32\LogFiles\HTTPERR&amp;#34;&lt;/span&gt; /C &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;cmd /c del /f /q @path&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This script, just as the previous one, will search for all files more than 10 days old and delete them. We don’t need to search for subfolders in this case because of Windows storing all HTTPERR logs at the same level. After running the task, we can open the folder properties and check that the used space will be the roughly the same over the days:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/09/keeping-our-windows-server-clean/httperr-space-green-check.jpg&#34; alt=&#34;Folder properties after cleanup&#34;&gt;&lt;/p&gt;
&lt;p&gt;(I know, still 1 GB after cleanup, gotta do something about those bad requests!)&lt;/p&gt;
&lt;h3 id=&#34;compressing-files&#34;&gt;Compressing files&lt;/h3&gt;
&lt;p&gt;If we need to comply with strict security/​auditing policies, and if we don’t have a backup device with enough capacity, deleting old files might not be an option. If that’s the case, we can compress the files to save space on disk.&lt;/p&gt;
&lt;p&gt;So an alternative would be to create a script to compress the files instead of deleting them using the &lt;code&gt;compact&lt;/code&gt; command. This is an example of a batch file that will compress all files in the IIS LogFiles folder that are more than 10 days old.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CompressIISLogs.bat&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;forfiles /D -10 /P &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\inetpub\logs\LogFiles&amp;#34;&lt;/span&gt; /S /C &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;cmd /c compact @path&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And of course, we can create more scripts for other locations, like the &lt;code&gt;C:\Windows\Temp&lt;/code&gt; folder for example. I mentioned earlier that my website creates a lot of XML and PNG files: I have another script whose mission is keeping those folders at bay, deleting forecast files that haven’t been used for more than one day (the local forecast will be outdated and would need to refresh it from the external web service anyway).&lt;/p&gt;
&lt;h3 id=&#34;more-resources-from-microsoft&#34;&gt;More resources from Microsoft&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/forfiles&#34;&gt;forfiles syntax and usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/windows/win32/http/configuring-http-server-api-error-logging&#34;&gt;Configuring HTTP server logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/iis/manage/provisioning-and-managing-iis/managing-iis-log-file-storage&#34;&gt;Managing IIS Log folder&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </content>
    </entry>
  
</feed>
