Skip to content

IIS Discovery Phase: Commands for a Single Website

Category: IIS Configuration Discovery Tags: IIS, PowerShell, web server discovery, site configuration, troubleshooting

This document provides every possible PowerShell command for the Discovery phase.

It focuses on one website at a time, using [SITE_NAME] to specify the website.

It assumes no prior knowledge of the setup (no site names, paths, or hostnames).

It clarifies how to map a website to its site ID (e.g., ID 1 maps to W3SVC1 log folder).

It retrieves the most recent log file for the website as [LOG_FILE].

Commands cover the website’s settings, log directory, log file, API paths (e.g., /api/ requests, web apps, URL patterns), bindings, application pool, and server-level details (services, features, network diagnostics).

Placeholders are marked in square brackets (e.g., [SITE_NAME]).

Each placeholder has a preceding command to retrieve its value.

Commands use literal values where possible and handle errors for missing features.

Commands and descriptions are separated by blank lines for readability.

Run all commands in PowerShell as Administrator to access IIS configurations.

Web Server Installation Verification

Get-WindowsFeature -Name Web* | Select-Object Name, DisplayName, Installed, Description, DependsOn | Sort-Object Name | Format-Table -AutoSize

What it does:

Lists all web server components (e.g., core IIS, management tools, FTP).

Shows installation status, descriptions, and dependencies.

Helps confirm if IIS and related features are installed.

IIS Service Status Check

Get-Service | Where-Object { $_.Name -like '*W3SVC*' -or $_.Name -like '*IIS*' -or $_.Name -like '*WAS*' -or $_.Name -like '*HTTP*' -or $_.Name -like '*MSFTPSVC*' -or $_.Name -like '*SMTPSVC*' } | Select-Object Name, DisplayName, Status, StartType, DependentServices | Format-Table -AutoSize

What it does:

Lists services related to the web server, FTP, or email (SMTP).

Shows service name, display name, status, startup type, and dependencies.

Helps verify if IIS-related services are running.

Website Enumeration

Get-Website | Select-Object Name, ID, @{Name='LogDirectory';Expression={$_.LogFile.Directory + '\W3SVC' + $_.ID}}, State, PhysicalPath, EnabledProtocols, @{Name='Bindings';Expression={$_.Bindings.Collection | ForEach-Object { $_.Protocol + '://' + $_.BindingInformation }}} | Format-Table -AutoSize

What it does:

Lists every website’s name, ID (e.g., 1 maps to W3SVC1), log directory, status, folder path, protocols, and bindings.

Use to choose a website name for [SITE_NAME].

Shows the W3SVC[ID] log folder for each website.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Default Website Selection

Get-Website | Select-Object -ExpandProperty Name | Select-Object -First 1

What it does:

Gets the name of one website (e.g., "Default Web Site").

Use as [SITE_NAME] in later commands.

Picks the first website if multiple exist.

Site ID Retrieval

Get-Website | Where-Object { $_.Name -eq '[SITE_NAME]' } | Select-Object -ExpandProperty ID

What it does:

Gets the site ID (e.g., 1 for W3SVC1) for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the previous command.

Identifies the W3SVC[ID] log folder for the website.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Log Directory Location

Get-Website | Where-Object { $_.Name -eq '[SITE_NAME]' } | Select-Object @{Name='LogDirectory';Expression={$_.LogFile.Directory + '\W3SVC' + $_.ID}}

What it does:

Gets the log directory for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Returns the path (e.g., C:\inetpub\logs\LogFiles\W3SVC1).

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Recent Log File Discovery

Get-ChildItem -Path (Get-Website | Where-Object { $_.Name -eq '[SITE_NAME]' } | Select-Object -ExpandProperty LogFile.Directory)\W3SVC*(Get-Website | Where-Object { $_.Name -eq '[SITE_NAME]' } | Select-Object -ExpandProperty ID) -Include *.log -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1 | Select-Object @{Name='LogFile';Expression={$_.FullName}}, LastWriteTime | Format-Table -AutoSize

What it does:

Gets the most recent log file for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Returns the file path (e.g., C:\inetpub\logs\LogFiles\W3SVC1\u_ex251103.log) as [LOG_FILE].

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Log File Content Analysis

Get-Content -Path '[LOG_FILE]' -Tail 100 -ErrorAction SilentlyContinue | Format-Table -AutoSize

What it does:

Shows the last 100 lines from [LOG_FILE].

Replace [LOG_FILE] with the path from the most recent log file command.

Includes request details like URLs, IP addresses, and status codes.

Placeholder: [LOG_FILE] (e.g., C:\inetpub\logs\LogFiles\W3SVC1\u_ex251103.log).

API Request Detection

Get-Content -Path '[LOG_FILE]' -ErrorAction SilentlyContinue | Select-String -Pattern '/api/' | Select-Object LineNumber, Line | Format-Table -AutoSize

What it does:

Searches [LOG_FILE] for requests containing “/api/”.

Replace [LOG_FILE] with the path from the most recent log file command.

Shows line numbers and request details to identify API activity.

Placeholder: [LOG_FILE] (e.g., C:\inetpub\logs\LogFiles\W3SVC1\u_ex251103.log).

Web Application Discovery

Get-WebApplication -Site '[SITE_NAME]' | Select-Object Path, PhysicalPath, ApplicationPool, EnabledProtocols, @{Name='VirtualDirectories';Expression={(Get-WebVirtualDirectory -Application $_.Path -Site '[SITE_NAME]' -ErrorAction SilentlyContinue).Path}} | Format-Table -AutoSize

What it does:

Lists web applications and subfolders for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Includes URL paths (e.g., /api) that may be API endpoints.

Shows physical paths, app pools, protocols, and virtual directories.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

URL Rewrite Rule Analysis

Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter "system.webServer/rewrite/rules" -Location "[SITE_NAME]" -Name * -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Rules | Where-Object { $_.Pattern -like '*api*' } | Select-Object Name, Pattern, @{Name='ActionUrl';Expression={$_.Action.Url}} | Format-Table -AutoSize

What it does:

Lists URL rewrite rules containing “api” for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Runs only if the URL Rewrite module is installed.

Shows rule names, patterns, and redirected URLs.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Website Configuration Settings

Get-WebConfiguration -Filter 'system.applicationHost/sites/site' | Where-Object { $_.Name -eq '[SITE_NAME]' } | Select-Object @{Name='SiteName';Expression={$_.Name}}, @{Name='DefaultDocument';Expression={$_.GetChildElement('defaultDocument').Enabled}}, @{Name='DirectoryBrowsing';Expression={$_.GetChildElement('directoryBrowse').Enabled}}, @{Name='Compression';Expression={$_.GetChildElement('httpCompression').Enabled}} | Format-Table -AutoSize

What it does:

Shows configuration settings for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Includes default document, directory browsing, and compression settings.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Application Pool Association

Get-Website | Where-Object { $_.Name -eq '[SITE_NAME]' } | Select-Object -ExpandProperty ApplicationPool

What it does:

Gets the application pool name for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Returns the name to use as [APP_POOL_NAME].

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Application Pool Configuration

Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter "system.applicationHost/applicationPools/add[@name='[APP_POOL_NAME]']" -Name * | Select-Object Name, ManagedPipelineMode, ManagedRuntimeVersion, @{Name='RecyclingSchedule';Expression={$_.Recycling.PeriodicRestart.Schedule.Collection}} | Format-Table -AutoSize

What it does:

Shows settings for the application pool named [APP_POOL_NAME].

Replace [APP_POOL_NAME] with the name from the previous command.

Includes processing mode, .NET version, and recycling schedule.

Placeholder: [APP_POOL_NAME] (e.g., "DefaultAppPool").

SSL Certificate Validation

Get-WebBinding -Name '[SITE_NAME]' | Where-Object { $_.Protocol -eq 'https' } | Select-Object @{Name='SiteName';Expression={$_.GetParentElement().Name}}, @{Name='Binding';Expression={$_.BindingInformation}}, CertificateHash, @{Name='CertificateDetails';Expression={(Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq $_.CertificateHash } | Select-Object Subject, NotAfter, Issuer)}} | Format-Table -AutoSize

What it does:

Lists SSL certificate details for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Shows certificate hash, subject, expiration, and issuer for HTTPS bindings.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Hostname Extraction

Get-WebBinding -Name '[SITE_NAME]' | ForEach-Object { $hostName = ($_.BindingInformation -split ':')[1]; if ($hostName -and $hostName -ne '*') { $hostName } }

What it does:

Gets the hostname (e.g., www.example.com) for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Returns the hostname to use as [HOSTNAME].

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Network Connectivity Test

Test-Connection -ComputerName '[HOSTNAME]' -Count 2 -ErrorAction SilentlyContinue | Select-Object Address, ResponseTime, Status | Format-Table -AutoSize

What it does:

Pings the hostname [HOSTNAME].

Replace [HOSTNAME] with the hostname from the previous command.

Checks network reachability and response time.

Placeholder: [HOSTNAME] (e.g., www.example.com).

Network Path Analysis

tracert -h 10 '[HOSTNAME]'

What it does:

Runs a traceroute to [HOSTNAME].

Replace [HOSTNAME] with the hostname from the hostname command.

Shows the network path to the hostname.

Placeholder: [HOSTNAME] (e.g., www.example.com).

Port Accessibility Testing

Get-WebBinding -Name '[SITE_NAME]' | ForEach-Object { $port = ($_.BindingInformation -split ':')[2]; $hostName = ($_.BindingInformation -split ':')[1]; if ($port -and ($port -eq '80' -or $port -eq '443')) { Test-NetConnection -ComputerName ($hostName -eq '*' ? 'localhost' : $hostName) -Port $port -ErrorAction SilentlyContinue | Select-Object ComputerName, RemotePort, TcpTestSucceeded } } | Format-Table -AutoSize

What it does:

Tests ports (80 for HTTP, 443 for HTTPS) for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Checks if the ports are open and reachable.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

DNS Resolution Verification

Resolve-DnsName -Name '[HOSTNAME]' -ErrorAction SilentlyContinue | Select-Object Name, Type, Address | Format-Table -AutoSize

What it does:

Looks up DNS records for [HOSTNAME].

Replace [HOSTNAME] with the hostname from the hostname command.

Shows IP addresses and DNS record types.

Placeholder: [HOSTNAME] (e.g., www.example.com).

Failed Request Tracing Configuration

Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/tracing/traceFailedRequests' -Location '[SITE_NAME]' -Name * -ErrorAction SilentlyContinue | Select-Object @{Name='Enabled';Expression={$_.Enabled}}, @{Name='TraceDirectory';Expression={$_.Directory}} | Format-Table -AutoSize

What it does:

Checks if failed request logging is enabled for the website named [SITE_NAME].

Replace [SITE_NAME] with the name from the website name command.

Shows the trace directory if enabled.

Placeholder: [SITE_NAME] (e.g., "Default Web Site").

Trace Log Directory Location

Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/tracing/traceFailedRequests' -Name * -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Directory

What it does:

Gets the folder for failed request logs.

Returns the path to use as [TRACE_DIRECTORY].

Typically returns a path like C:\inetpub\logs\FailedReqLogFiles.

Failed Request Log Files

Get-ChildItem -Path '[TRACE_DIRECTORY]' -Recurse -Include *.fr* -ErrorAction SilentlyContinue | Select-Object FullName, LastWriteTime, Length | Format-Table -AutoSize

What it does:

Lists all failed request log files in [TRACE_DIRECTORY].

Replace [TRACE_DIRECTORY] with the path from the previous command.

Shows file paths, modification times, and sizes.

Placeholder: [TRACE_DIRECTORY] (e.g., C:\inetpub\logs\FailedReqLogFiles).

Session Transcript Logging

Start-Transcript -Path 'C:\Troubleshooting\IIS_Discovery_Log.txt' -Append

What it does:

Starts logging all commands and their output to a file.

Run before other commands.

Stop logging with Stop-Transcript.