AppCmd, in combination with WinRM, is the Windows Server IIS systems administrator’s swiss-army knife for his daily routine. This post introduces AppCmd and provides a lot of AppCmd examples.
AppCmd.exe is a command-line utility to manage IIS 7+ web servers. It exposes all important IIS server management functionality available through a set of intuitive management objects that can be manipulated through the cmd.exe or PowerShell command-line, or through PowerShell scripts. In this post you’ll find more information about AppCmd usage and examples.
IIS server management with AppCmd
AppCmd provides the ability to administer and maintain Windows Server IIS editions without a graphical user interface (or GUI), like Windows Server Core for example. Using AppCmd you can administer those IIS servers without the need for writing extensive scripts.
Some tasks you can use AppCmd for are:
- Create and configure websites, applications, application pools and IIS virtual directories.
- Starting and stopping of sites, and recycling application pools.
- List currently running worker processes and examine currently executing requests
- Search, manipulate (add, edit, clear / remove), import/export IIS and ASP.NET configurations.
In this AppCmd introduction post I’ll provide AppCmd examples to administer (parts of) Internet Information Services (IIS).
Note: this post is a rewrite and translation of my old, Dutch article “AppCmd fu – inleiding en voorbeelden“. That article is now removed and 301 redirects to this post.
AppCmd usage and AppCmd command examples
AppCmd uses the following syntaxis for its commands:
AppCmd (command) (object-type) <identifier> </parameter1:value1 ...>
Some of AppCmd commands are
stop. Those commands are used for the following object-types:
vdir (virtual directory),
apppool (application pool),
wp (worker process),
binding. Of course not every object-type can be stopped or started, look up the available options using
AppCmd /? AppCmd site /? AppCmd config /? AppCmd list apppool /?
Now let’s dive into AppCmd with some examples! 🙂
List website information
Appcmd list site "Default Web Site"
This command provides some valuable information about the requested website, the Default Web Site in this case. Its output is:
SITE "Default Web Site" (id:1,bindings:http/*:80:,state:Started)
And this tells us the “Default Web Site” SITE-object has IIS website identifier 1, listens on all configured IP addresses configured for this web server (
*), on port 80 and the state of the website is “Started”.
List website information with a parameter
By slightly altering the above
list site AppCmd command, you can list all websites matching a condition. You provide the condition as an AppCmd parameter, for example to list all sites that are in state Stopped:
AppCmd list sites /state:Stopped
Now you can start all those websites to make your customers happy. But you may not want to start a site that hasn’t got
serverAutoStart configured (it must be stopped for a reason then). Let’s add that as a condition:
AppCmd list sites /serverAutoStart:false /state:Stopped
Stop a website, start a website with AppCmd
Use the following AppCmd commands to stop a website or to start a website. Substitute “example.com” with the website name in question.
AppCmd stop site "example.com" AppCmd start site "example.com"
Starting and stopping a website with AppCmd is as easy as that.
Stop, start and recycle application pools
Besides stopping and starting a website, you can use AppCmd to stop an application pool, start an application pool or recycle an application pool (recycling gracefully stops and restarts the applications pool). Once again, substitute “example.com”, but now with the application pool name in question.
AppCmd stop AppPool "example.com" AppCmd start AppPool "example.com" AppCmd start AppPool "example.com" /autoStart:true AppCmd recycle AppPool "example.com"
Start all stopped application pools in a loop
Because AppCmd supports the piping of additional commands, a
-xml) parameter to generate XML formatted output, and a
/in parameter to read and operate on XML input, it’s possible to pipe multiple AppCmd commands to start all stopped application pools in a single command / loop.
AppCmd list AppPools /state:stopped /xml | AppCmd start AppPool /in AppCmd list AppPools /state:stopped /xml | AppCmd start AppPool /in AppCmd list AppPools /state:stopped /autostart:true /xml | AppCmd start AppPool /in
The latter is my favorite. In a nutshell, what this does is:
- List all application pools in state Stopped, and generate XML formatted output (
- Pipe that XML output to AppCmd, using
/in, which is then fed to the
The last one has a condition
/autostart:true meaning, list only application pools that are supposed to be in Started state (because IIS starts an application pool with this setting automatically).
Protip: learn how to set application pools to recycle on specific times, not by regular time interval.
Set Integrated Managed PipelineMode for application pools
IIS 6.0 is now really ancient history, and an application pool set to Classic Pipeline Mode should be as well. Let’s force all Classic application pools to Integrated Pipeline Mode:
AppCmd list AppPools /xml | AppCmd set AppPool -managedpipelinemode:Integrated /in
In IIS 7, application pools run in one of two modes: integrated mode and classic mode. The application pool mode affects how the server processes requests for managed code. If a managed application runs in an application pool with integrated mode, the server will use the integrated request-processing pipelines of IIS and ASP.NET to process the request. However, if a managed application runs in an application pool with classic mode, the server will continue to route requests for managed code through Aspnet_isapi.dll, which processes requests the same as if the application were running in IIS 6.0.
Most managed applications should run successfully in application pools with integrated mode, but you may have to run applications in classic mode for compatibility reasons. Test the applications that are running in integrated mode first to determine whether you have to use classic mode.
Protip: learn how to target multiple ASP.NET versions with AppCmd.
Set a .NET Framework version for an application pool
If your web server hosts ASP.NET applications, you must know which version of the .NET Framework these applications use before you assign them to application pools. IIS 7 preloads the .NET Framework version that is specified for the application pool. Only one version of the .NET Framework can be loaded in an application pool. Applications in the same application pool must therefore use the same .NET Framework version; otherwise, their associated worker processes will not run.
Applications that do not use managed code or enable any managed server modules do not have this requirement. These applications can explicitly state that no version of the .NET Framework should be preloaded.
To change the .NET Framework version that an application pool runs, use the following command syntax:
AppCmd set AppPool /apppool.name:string /managedRuntimeVersion:string
The command quits with a confirmation:
APPPOOL object "string" changed.
Use v4.0 or v2.0 as the managedRuntimeVersionstring:
AppCmd set AppPool /apppool.name:saotn.org /managedRuntimeVersion:v4.0
PHP fastCgi configuration
AppCmd also exposes the fastCgi configuration of IIS, allowing you to change the current PHP fastCgi configuration. I’ve blogged on more than one occasion about IIS + PHP + fastCgi + AppCmd: here, here.
For all commands below, remember to escape single quotes
' in PowerShell with a back tick
`! Set or change an fastCgi PHP configuration setting:
AppCmd set config /section:system.webServer/fastCgi /[fullPath='c:\php7\php-cgi.exe'].instanceMaxRequests:10000 /commit:apphost
instanceMaxRequests was set to 5000, this command updates it to 10000 by overwriting the configuration with the new settings. To add an fastCgi property you can use almost the exact same command. For example if you want to add
signalBeforeTerminateSeconds as a property:
AppCmd set config /section:system.webServer/fastCgi /[fullPath='c:\php7\php-cgi.exe'].signalBeforeTerminateSeconds:5 /commit:apphost
Change fastCgi environment variables:
AppCmd set config /section:system.webServer/fastCgi /[fullPath='c:\php7\php-cgi.exe'].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS'].value:5001 /commit:apphost
List PHP handler for a website
Use AppCmd to list the configured handler for a website to handle PHP, by name or extension path
appcmd list config SITENAME /section:handlers /text:[path='*.php'].scriptProcessor appcmd list config SITENAME /section:handlers /text:[name='PHP'].scriptProcessor
Add or change a PHP Handler to a website only via AppCmd
You can use the following two appcmd commands to: 1) remove the current PHP handler for a website, and 2) add a new one:
appcmd.exe set config "example.com" -section:system.webServer/handlers /-"[name='PHP']" appcmd.exe set config "example.com" -section:system.webServer/handlers /+"[name='PHP',path='*.php',verb='',modules='FastCgiModule',scriptProcessor='c:\php7\php-cgi.exe',resourceType='File', requireAccess='Script']"
Return to the default web server configuration:
appcmd clear config "example.com" -section:system.webServer/handlers
Remove PHP 5.4 fastCgi handler
To completely remove an fastCgi handler, for example for PHP 5.4, use:
AppCmd set config /section:system.webServer/fastCgi /-"[fullPath='c:\php54\php-cgi.exe']" /commit:apphost
To delete the fastCgi configuration. To delete its IIS handler, use:
AppCmd clear config /section:handlers -[name='PHP']
List application pool username and password
An application pool often is configured to run as an unprivileged user. The Application Pool Identity is set to a custom account instead of a built-in account. You can lookup the application pool credentials using these two commands:
AppCmd list AppPool "example.com" /text:processModel.username AppCmd list AppPool "example.com" /text:processModel.password
Create a website using AppCmd
To use AppCmd to create a website, you can use, and extend, the following example:
Appcmd add site /name:"example.com" /id:821398 /physicalPath:"c:\Inetpub\wwwroot\examplecom" /limits.maxconnections:1000 /serverAutostart:true
This creates a website called “example.com”, with IIS identifier 821398, it uses
c:\Inetpub\wwwroot\examplecom as its physical path. A limit of 1000 simultaneous connections is set, as is the Autostart property.
In earlier blog posts I provided some more examples to create application pool and websites with AppCmd: Add websites and application pools to IIS 7.5, 8.0 with PowerShell, in a for loop.
AppCmd with WinRM
I mentioned WinRM, or Windows Remote Management, in the introduction of this article. You can use all these AppCmd commands with WinRM on remote web serves. Neat! 🙂 An example is to conditionally start Application Pools on remote IIS web servers.
This is ideal for central IIS management situations.