API Endpoint Discovery from IIS Server
This guide explains how to discover all API endpoints from an IIS server's API application pool using PowerShell reflection without external tools.
Step 1: Find API Application Pool Path
Get-IISApplication | Where-Object {$_.Path -like "*api*"} | Select Path, PhysicalPath
What it does:
- Get-IISApplication
- Retrieves all IIS applications configured on the server
- Where-Object {$_.Path -like "*api*"}
- Filters applications whose path contains "api"
- Select Path, PhysicalPath
- Shows both the virtual path (like "/api") and physical disk path (like "C:\inetpub\wwwroot\api")
Purpose: Locates where your API application files are stored on disk.
Step 2: List Available DLL Files
Get-ChildItem *.dll | Select Name
What it does:
- Get-ChildItem *.dll
- Lists all .dll files in the current directory (bin folder)
- Select Name
- Shows only the filename of each DLL
Purpose: Identifies which assemblies contain your API code. Look for files named like <YourProject>.Api.dll
or <CompanyName>.WebApi.dll
.
Step 3: Load the API Assembly
$assembly = [System.Reflection.Assembly]::LoadFile("<full_path_to_api_dll>")
What it does:
- [System.Reflection.Assembly]::LoadFile()
- .NET reflection method that loads a compiled assembly into memory
- <full_path_to_api_dll>
- Replace with complete path like "C:\inetpub\wwwroot\api\bin\YourApi.dll"
- $assembly
- Stores the loaded assembly object for further inspection
Purpose: Loads your API's compiled code so we can examine its structure programmatically.
Step 4: Find All Controller Classes
$assembly.GetTypes() | Where-Object {$_.Name -like "*Controller*"} | ForEach-Object {
Write-Host $_.Name
$_.GetMethods() | Where-Object {$_.IsPublic} | Select-Object Name
}
What it does:
- $assembly.GetTypes()
- Gets all classes/types defined in the assembly
- Where-Object {$_.Name -like "*Controller*"}
- Filters to classes with "Controller" in the name
- ForEach-Object
- Loops through each controller class
- Write-Host $_.Name
- Prints the controller class name
- $_.GetMethods()
- Gets all methods (functions) in that controller
- Where-Object {$_.IsPublic}
- Filters to only public methods (API endpoints are public)
- Select-Object Name
- Shows method names
Purpose: Discovers all API controller classes and their public methods, which represent your API endpoints.
Step 5: Extract Endpoints with Route Information
$controllers = $assembly.GetTypes() | Where-Object {$_.BaseType.Name -eq "ApiController"}
$controllers | ForEach-Object {
$controller = $_
$controller.GetMethods() | Where-Object {$_.IsPublic -and $_.DeclaringType -eq $controller} |
ForEach-Object { "$($controller.Name): $($_.Name)" }
}
What it does:
- Where-Object {$_.BaseType.Name -eq "ApiController"}
- Finds classes that inherit from ApiController (Web API 2) or ControllerBase (Web API Core)
- $_.DeclaringType -eq $controller
- Ensures we only get methods defined in this controller (not inherited ones)
- "$($controller.Name): $($_.Name)"
- Formats output as "ControllerName: MethodName"
Purpose: Creates a clean list showing which controller contains which endpoint methods.
Step 6: Get Route Attributes (Advanced)
$controllers | ForEach-Object {
$controller = $_
$controller.GetMethods() | ForEach-Object {
$method = $_
$attributes = $method.GetCustomAttributes($true)
$routeAttr = $attributes | Where-Object {$_.GetType().Name -like "*Route*"}
if($routeAttr) {
"$($controller.Name.Replace('Controller','')): $($method.Name) -> $($routeAttr.Template)"
}
}
}
What it does:
- $method.GetCustomAttributes($true)
- Gets all attributes applied to the method (like [HttpGet], [Route])
- Where-Object {$_.GetType().Name -like "*Route*"}
- Finds routing attributes
- $routeAttr.Template
- Extracts the actual route template (like "api/users/{id}")
- Replace('Controller','')
- Removes "Controller" suffix for cleaner output
Purpose: Shows the actual HTTP routes/URLs for each endpoint, not just method names.
Example Output
After running these commands, you'll see output like:
UsersController: GetUsers
UsersController: GetUser
UsersController: CreateUser
UsersController: UpdateUser
UsersController: DeleteUser
ProductsController: GetProducts
ProductsController: GetProduct
Common API Assembly Naming Patterns
Look for DLLs named:
- <ProjectName>.Api.dll
- <ProjectName>.WebApi.dll
- <CompanyName>.Services.dll
- Api.dll
- WebApi.dll
Troubleshooting
If no controllers found:
- Try Where-Object {$_.BaseType.Name -eq "ControllerBase"}
for .NET Core APIs
- Check if DLL is the right one by examining $assembly.GetTypes() | Select Name
If assembly won't load:
- Ensure you have read permissions to the bin directory
- Try copying DLL to a temp folder first
- Check if DLL has dependencies that aren't loaded