iis_bridge Documentation

Copyright © 2014 - Author: Kourosh Parsa

iis_bridge is a python package for manipulating IIS and monitoring iis pools' memory on windows.
IIS = Internet Information Services. It's a .net web app server.

iis_bridge has been tested with python 2.7 on:


Python 3 support has also been added.

How to install the package:

1
pip install iis_bridge

Important: You must run python in a terminal with administrator privileges in order to use most of the iis operations.

Installing/restarting iis

iis_bridge can install iis for you as shown below:
1
2
3
4
5
6
7
8
import iis_bridge as iis
# to install iis:
iis.install()
 
print("iis version %s" % iis.get_version())
 
# to reset iis:
iis.iisreset()

Retrieving sites and pools

Here is how you can retrieve a list of application pools and site:
1
2
3
4
5
import iis_bridge as iis
# to list the pool names:
print(iis.get_pool_names())
# to list the site names:
print(iis.get_site_names())

Application Pools

How to create

Here is the create method signature:
1
2
3
def create(name,
    runtime_version="4.0",
    pipeline_mode="Integrated"):
As you can see, by default, a 4.0 pool with integrated mode is created.
To create a pool if it does not already exist:
1
2
3
4
5
import iis_bridge.pool as pool
if not pool.exists("some_pool"):
    pool.create("some_pool")
if pool.is_running("some_pool"):
    print("The pool is running!")

How to stop/start

You can start/stop pools like so:
1
2
3
4
import iis_bridge.pool as pool
pool.stop("some_pool")
pool.stat("some_pool")
pool.restart("some_pool")

How to configure

Here are the parameters that can be used: You can configure the pool as in the following example:
1
2
3
4
5
6
7
8
9
10
11
12
import iis_bridge.pool as pool
pool.config("DefaultAppPool", thirty_two_bit=False)
pool.config("DefaultAppPool", identity="ApplicationPoolIdentity")
pool.config("DefaultAppPool", identity="LocalService")
pool.config("DefaultAppPool", identity="LocalSystem")
pool.config("DefaultAppPool", identity="NetworkService")
pool.config("DefaultAppPool", identity="SpecificUser", username="my_username", password="my_pass")
# to set the idle timeout to 30 minutes:
pool.config("DefaultAppPool", idle_timeout="00:30:00")
# note that small values ()like 10 seconds) are not allowed
 
pool.config("DefaultAppPool", pipeline_mode="Classic")

How to delete

1
2
3
import iis_bridge.pool as pool
if pool.exists("some_pool"):
    pool.delete("some_pool")

Sites

How to create

1
2
3
4
5
6
7
# to add an iis site on port 5050:
import iis_bridge.site as site
#       site name, port number, app directory, app pool name
site.create("mysite", 5050, r"C:\inetpub\wwwroot\myapp", "mypool")
 
# now to list the site names:
print(iis.get_site_names())

Memory Monitoring

iis_bridge allows you to monitor the worker process memory. Below are the relevant methods signatures.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def monitor_with_load(iterations, # this is the number of iterations of sending the requests = Total duration of sending requests
                  urls,  # list of urls to send the requests to. If 'all' is specified, it retrieves the app pools and sends requests to http://localhost:[port]
                  rate,  # how many parallel requests to send per iteration
                  mem_type='WorkingSetPrivate'# the type of memory to monitor
                  mem_unit='KB',           # the units of memory to monitor
                  timeout=15               # http timeout in seconds
                  )
 
def html_report(datasets,  # the datasets to plot
    mem_type='WorkingSetPrivate', # the type of memory to monitor
    mem_unit='KB',       # the memory unit: Bytes, KB, MB
    output_path='out.html', # the path where to save the html report
    pools_to_monitor=None # list of pools to plot. If not specified, all pools will be plotted
    ):
Here is an example how to monitor the private working set memory of all the application pools for 6 seconds while sending 12 parallel GET http requests per second. The http_report method generates an out.html in the current directory. You can specify output path using the output_path parameter.
1
2
3
import iis_bridge.mon as mon
datasets = mon.monitor_with_load(6, 'all', 12, timeout=30) # timeout is in seconds - default=15sec
mon.html_report(datasets)
which results in:

The example above may not be practical as in reality you'd have various context roots and various http request types.
The example below shows how to send various types of requests to custom urls and monitor the app pool memory:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import iis_bridge.mon as mon
import iis_bridge.site as site
 
app1_port = site.get_port("App1")
app2_port = site.get_port("App2")
 
urls = ["http://localhost:%s?add=3,4,5" % app1_port,\
        "http://localhost:%s" % app2_port,\
        ["http://localhost:190/CalcService.svc/multiply", "POST", {"list":[1,2,3]}, "json"],\
        ["http://localhost:190/CalcService.svc/multiply", "POST", "<list><int>1<int><int>2<int><int>3<int></int></int></int></int></int></int></list>", "xml"]
       ]
pools = ["App1", "App2"]
mem_unit = 'MB'
duration = 10 # seconds
reqs_per_sec = 16 # how many request to send per second
datasets = mon.monitor_with_load(duration, urls, reqs_per_sec, mem_unit=mem_unit)
mon.html_report(datasets, pools_to_monitor=pools, mem_unit=mem_unit)
print("Done")

Note that
1
site.get_port("App1")
allows you to get the port number of a site called App1 which eliminates hard-coding port numbers hence reducing maintanance. If you specify a url as a string, the default behaviour (GET request html type) will be assumed.
If you wish to specify the request, you need to specify it as:
urls = [ [url, request method, request data, request type], ... ] where only url parameter is required.

The mem module is aimed to retrieve memory information of the iis pools. You can use the mem.get_workers() to get the worker processes (w3wp.exe processes).
Note: By default, iis will destroy worker processes after a while being idle so if get_workers() does not return anything, then you need to send some requests to the site it make it active.
Here is a usage example:
1
2
3
4
import iis_bridge.mem as mem
for w in mem.get_workers():
    print(str(w))
output>> DefaultAppPool: pid=12768 WorkingSetPrivate=10052

http load

Now the question is whether users can use the load generator with another monitoring tool. Yes. Here is the load_get() method signature:
1
2
3
4
5
6
http_thread = load_gen.HttpFlood(iterations, # number of iterations
        urls, # the list of urls to send http requests to
        rate, # the number of reuqests to send per interval (default per second)
        interval=interval, # (optional default=1 second) the interval between iterations of parallel requests
        timeout=15         # http timeout in seconds
        )

And here is how to use it:
1
2
3
4
5
6
7
8
9
10
11
import iis_bridge.load_gen as load_gen
# send 6 requests per second for 10 seconds:
http_thread = load_gen.HttpFlood(10, urls, 6)
http_thread.start()
# do your own monitoring if you prefer another tool
http_thread.join() # wait for the http generator to stop
print("Number of successful requests sent: %i" % http_thread.total_resp_received)
print("Average response time: %f seconds" % http_thread.avg_res_time)
Note that the default interval is 1 second and rate is the number of parallel requests to send per iteration.

Registering asp

In order to deploy asp web apps on iis, you need to register asp on iis.
You can register asp 4.0 and 2.0 on iis:
1
iis.register_asp()


Installing ISAPI:

ISAPI (Internet Server Application Programming Interface) is an N-tier API of IIS. To enable ISAPI on IIS:
1
2
import iis_bridge.isapi as isapi
isapi.enable()

Installing WCF

You can install WCF (windows communication foundation) services.
Here is how to install all WCF services:
1
2
import iis_bridge as iis
iis.install_wcf()

This will install all the WCF services, but if you want to specify some WCF services to install, you can as shown below:
1
2
3
# to install WCF-Services45 and CF-HTTP-Activation45:
import iis_bridge as iis
iis.install_wcf(["WCF-Services45", "WCF-HTTP-Activation45"])