alexsusanu@docs:API Endpoint Discovery from IIS Server $
alexsusanu@docs
:~$ cat API Endpoint Discovery from IIS Server.md

HomeCLI → API Endpoint Discovery from IIS Server

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

Last updated: 2025-08-26 20:00 UTC