Import-Module WebAdministration
# Get all websites
$sites = Get-ChildItem IIS:\Sites
# Initialize results array
$results = @()
foreach ($site in $sites) {
# Get all virtual directories for current site
$vdirs = Get-WebVirtualDirectory -Site $site.Name
foreach ($vdir in $vdirs) {
# Get application pool information if applicable
$appPool = ""
$appPath = $vdir.Path
if ($appPath -ne "/") {
$app = Get-WebApplication -Site $site.Name | Where-Object {$_.path -eq $appPath}
if ($app) {
$appPool = $app.applicationPool
}
}
# Get authentication settings
$auth = Get-WebConfigurationProperty -Filter "system.webServer/security/authentication/*" -Location "$($site.Name)$($vdir.Path)" -Name "enabled" -ErrorAction SilentlyContinue |
Where-Object {$_.Value -eq $true} |
Select-Object -ExpandProperty ItemXPath -ErrorAction SilentlyContinue
# Create custom object with all properties
$result = [PSCustomObject]@{
SiteName = $site.Name
VirtualPath = $vdir.Path
PhysicalPath = $vdir.PhysicalPath
ApplicationPool = $appPool
Authentication = if ($auth) { $auth.Split('/')[-1] } else { "Not Configured" }
Credentials = if ($vdir.userName) { $vdir.userName } else { "Pass-through" }
}
$results += $result
}
}
# Output results
$results | Format-Table -AutoSize
This script uses the WebAdministration module to query IIS configuration. Here's the breakdown:
1. First we import the WebAdministration module
2. We retrieve all IIS sites
3. For each site, we get all virtual directories
4. For each virtual directory, we collect:
- Site name
- Virtual path
- Physical path
- Associated application pool (if any)
- Authentication method
- Credentials being used
5. Finally, we output the collected data in table format
For virtual directories that are actually applications (have application pools), we need additional logic:
$app = Get-WebApplication -Site $site.Name | Where-Object {$_.path -eq $appPath}
if ($app) {
$appPool = $app.applicationPool
}
The authentication settings require querying the IIS configuration system:
Get-WebConfigurationProperty -Filter "system.webServer/security/authentication/*"
-Location "$($site.Name)$($vdir.Path)"
-Name "enabled"
-ErrorAction SilentlyContinue
If you prefer using appcmd.exe, here's a one-liner that outputs similar information:
appcmd list vdir /text:*
To parse this output in PowerShell:
appcmd list vdir /text:* | ForEach-Object {
$parts = $_ -split '"'
[PSCustomObject]@{
SiteName = $parts[1]
VirtualPath = $parts[3]
PhysicalPath = $parts[5]
}
}
To save the results for documentation or analysis:
$results | Export-Csv -Path "IIS_VirtualDirectories.csv" -NoTypeInformation
When working with IIS 8+, many administrators struggle to extract comprehensive virtual directory information through PowerShell. The common pitfalls include:
- Mixing up Web Applications with Virtual Directories
- Missing authentication configuration details
- Incomplete property mapping between IIS Manager and PowerShell outputs
Here's a robust script that extracts all required virtual directory properties:
Import-Module WebAdministration
$output = @()
Get-ChildItem IIS:\Sites | ForEach-Object {
$site = $_
Get-WebVirtualDirectory -Site $site.Name | ForEach-Object {
$vdir = $_
# Get authentication settings
$auth = Get-WebConfigurationProperty
-Filter "system.webServer/security/authentication/*"
-Name "enabled"
-PSPath "IIS:\Sites\$($site.Name)"
-Location $vdir.Path
$output += [PSCustomObject]@{
SiteName = $site.Name
VDirName = $vdir.Path.Split('/')[-1]
PhysicalPath = $vdir.PhysicalPath
AppPool = (Get-ItemProperty "IIS:\Sites\$($site.Name)\$($vdir.Path)" -Name applicationPool).Value
AnonymousAuth = ($auth | Where-Object { $_.ItemXPath -like "*anonymousAuthentication*" }).Value
WindowsAuth = ($auth | Where-Object { $_.ItemXPath -like "*windowsAuthentication*" }).Value
BasicAuth = ($auth | Where-Object { $_.ItemXPath -like "*basicAuthentication*" }).Value
}
}
}
$output | Format-Table -AutoSize
The script handles several technical nuances:
- Authentication Retrieval: Uses Get-WebConfigurationProperty to dig into security settings
- App Pool Association: Gets the actual application pool instead of just the containing site's pool
- Path Parsing: Properly handles nested virtual directory paths
For environments where WebAdministration module isn't available:
$namespace = "root\MicrosoftIISv2"
$sites = Get-CimInstance -Namespace $namespace -ClassName "IIsWebServerSetting"
foreach ($site in $sites) {
$vdirs = Get-CimAssociatedInstance -InputObject $site
-ResultClassName "IIsWebVirtualDirSetting"
foreach ($vdir in $vdirs) {
[PSCustomObject]@{
Server = $site.ServerComment
VDir = $vdir.Name.Split(',')[-1]
Path = $vdir.Path
AppPool = $vdir.AppPoolId
}
}
}
For integration with monitoring systems:
$output | ConvertTo-Json -Depth 5 | Out-File "iis_vdirs.json"
- Run PowerShell as Administrator when querying IIS
- Check if WebAdministration module is properly installed (Add-WindowsFeature Web-Scripting-Tools)
- For nested virtual directories, use Get-Item with full IIS provider path