How to Create a Virtual Directory in IIS from Batch Script
A virtual directory in IIS maps a URL path to a physical folder on the file system that may exist outside the website's root directory. This allows you to serve content from multiple disk locations under a single website URL structure without duplicating files or restructuring your storage layout.
In this guide, we will explore how to create, configure, and manage IIS virtual directories from a Batch Script using the appcmd.exe command-line tool.
Understanding Virtual Directories
A virtual directory creates an alias in the URL namespace that points to any physical folder on the server (or a network share). For example:
| URL Path | Physical Path | Type |
|---|---|---|
http://site.com/ | C:\inetpub\wwwroot | Website root |
http://site.com/downloads | D:\SharedFiles\Downloads | Virtual directory |
http://site.com/reports | \\FileServer\Reports | Virtual directory (UNC path) |
Without virtual directories, all content must reside within the website's root folder tree. Virtual directories break this limitation, allowing flexible content organization across drives, partitions, and network shares.
Method 1: Creating a Basic Virtual Directory
@echo off
setlocal
set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=CompanyIntranet"
set "vdir_alias=downloads"
set "vdir_path=D:\SharedFiles\Downloads"
:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)
:: Verify appcmd exists
if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found at: %appcmd%
echo IIS may not be installed or Management Tools are missing.
pause
exit /b 1
)
:: Verify the site exists
"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Website "%site_name%" not found in IIS.
pause
exit /b 1
)
:: Ensure the physical directory exists
if not exist "%vdir_path%" (
echo [ERROR] Physical path does not exist: %vdir_path%
echo Create the directory first or verify the path.
pause
exit /b 1
)
:: Check if the virtual directory already exists
"%appcmd%" list vdir /vdir.name:"%site_name%/%vdir_alias%" >nul 2>&1
if %errorlevel% equ 0 (
echo [INFO] Virtual directory "/%vdir_alias%" already exists on "%site_name%".
pause
exit /b 0
)
echo Creating virtual directory "/%vdir_alias%" on "%site_name%"...
"%appcmd%" add vdir /app.name:"%site_name%/" /path:"/%vdir_alias%" /physicalPath:"%vdir_path%"
if %errorlevel% equ 0 (
echo [SUCCESS] Virtual directory created.
echo URL path: /%vdir_alias%/
echo Maps to: %vdir_path%
) else (
echo [ERROR] Failed to create virtual directory.
echo Check that the app name "%site_name%/" is correct.
)
pause
The /app.name Parameter
The /app.name must include the trailing slash. For the root application of a site named "CompanyIntranet", the app name is CompanyIntranet/. For a sub-application, it would be CompanyIntranet/subapp/.
The trailing slash in /app.name:"%site_name%/" is required because it specifies the application path within the site. The root application of every IIS site has the path /, so the full application identifier is SiteName/. Omitting the trailing slash causes appcmd to fail to locate the application.
Method 2: Creating a Virtual Directory Pointing to a Network Share
Virtual directories can point to UNC paths, allowing IIS to serve files stored on remote file servers.
@echo off
setlocal
set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=CompanyPortal"
set "vdir_alias=shared-docs"
set "vdir_path=\\FileServer\Documents\Public"
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)
if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)
:: Verify the site exists
"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Site "%site_name%" not found in IIS.
pause
exit /b 1
)
:: Check if the UNC path is reachable
if not exist "%vdir_path%" (
echo [WARNING] UNC path is not currently reachable: %vdir_path%
echo The virtual directory will be created, but IIS will return
echo errors until the path becomes accessible.
echo.
set /p "proceed=Continue anyway? (Y/N): "
if /i not "!proceed!"=="Y" (
echo [CANCELLED]
pause
exit /b 0
)
)
:: Check for existing virtual directory
"%appcmd%" list vdir /vdir.name:"%site_name%/%vdir_alias%" >nul 2>&1
if %errorlevel% equ 0 (
echo [INFO] Virtual directory "/%vdir_alias%" already exists.
pause
exit /b 0
)
echo Creating virtual directory for UNC path...
"%appcmd%" add vdir /app.name:"%site_name%/" /path:"/%vdir_alias%" /physicalPath:"%vdir_path%"
if %errorlevel% equ 0 (
echo [SUCCESS] Virtual directory "/%vdir_alias%" created.
echo Points to: %vdir_path%
) else (
echo [ERROR] Failed to create virtual directory.
)
pause
When using UNC paths, the IIS application pool identity must have read permissions on the network share. By default, ApplicationPoolIdentity is a virtual account that does not have network access. You must either configure the pool to run under a domain account with appropriate share permissions, or set "Connect As" credentials on the virtual directory (shown below).
Setting Connect-As Credentials
To provide explicit credentials for accessing a network share:
@echo off
setlocal enabledelayedexpansion
set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=CompanyPortal"
set "vdir_alias=shared-docs"
set "username=DOMAIN\ServiceAccount"
set "password=SecureP@ssw0rd"
:: Verify the virtual directory exists before setting credentials
"%appcmd%" list vdir /vdir.name:"%site_name%/%vdir_alias%" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Virtual directory "%site_name%/%vdir_alias%" not found.
pause
exit /b 1
)
"%appcmd%" set vdir /vdir.name:"%site_name%/%vdir_alias%" /userName:"%username%" /password:"%password%"
if !errorlevel! equ 0 (
echo [OK] Credentials configured for UNC access.
) else (
echo [ERROR] Failed to set credentials.
)
pause
The password is stored in the IIS configuration file (applicationHost.config) and is encrypted using the IIS machine key. However, it is visible in plaintext within this Batch script file. In production environments, avoid hardcoding passwords in scripts. Consider reading the password from a secured file, prompting the user interactively, or using a domain account with a Group Managed Service Account (gMSA) which does not require password management.
Method 3: Creating Multiple Virtual Directories from a Configuration List
For provisioning a site with several virtual directories at once:
@echo off
setlocal enabledelayedexpansion
set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=DepartmentSite"
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)
if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)
:: Verify the site exists
"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Site "%site_name%" not found in IIS.
pause
exit /b 1
)
echo Provisioning virtual directories for "%site_name%"...
echo.
set "success=0"
set "skipped=0"
set "failed=0"
:: Define virtual directories: alias|physical_path
for %%D in (
"downloads|D:\PublicFiles\Downloads"
"uploads|D:\PublicFiles\Uploads"
"reports|D:\Reports\Monthly"
"images|E:\MediaLibrary\Images"
) do (
for /f "tokens=1,2 delims=|" %%A in (%%D) do (
set "alias=%%A"
set "path=%%B"
:: Check if already exists
"%appcmd%" list vdir /vdir.name:"%site_name%/!alias!" >nul 2>&1
if !errorlevel! equ 0 (
echo [SKIP] /!alias! - already exists.
set /a "skipped+=1"
) else (
if not exist "!path!" mkdir "!path!"
"%appcmd%" add vdir /app.name:"%site_name%/" /path:"/!alias!" /physicalPath:"!path!" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] /!alias! -^> !path!
set /a "success+=1"
) else (
echo [FAIL] /!alias! - could not create.
set /a "failed+=1"
)
)
)
)
echo.
echo Results: !success! created, !skipped! skipped, !failed! failed.
echo.
echo Current virtual directories:
"%appcmd%" list vdir /app.name:"%site_name%/"
pause
Method 4: Listing Existing Virtual Directories
@echo off
setlocal enabledelayedexpansion
set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=CompanyIntranet"
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)
if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)
:: Verify the site exists
"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Site "%site_name%" not found in IIS.
pause
exit /b 1
)
echo Virtual directories for "%site_name%":
echo =======================================
echo.
set "count=0"
for /f "delims=" %%V in ('"%appcmd%" list vdir /app.name:"%site_name%/" /text:path 2^>nul') do (
set "vpath=%%V"
set "physpath="
for /f "delims=" %%P in ('"%appcmd%" list vdir /vdir.name:"%site_name%!vpath!" /text:physicalPath 2^>nul') do set "physpath=%%P"
echo !vpath! -^> !physpath!
set /a "count+=1"
)
if !count! equ 0 (
echo [No virtual directories found]
)
echo.
echo Total: !count! virtual directories
pause
Method 5: Deleting a Virtual Directory
@echo off
setlocal
set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=CompanyIntranet"
set "vdir_alias=old-reports"
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)
if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)
:: Check if the virtual directory exists
"%appcmd%" list vdir /vdir.name:"%site_name%/%vdir_alias%" >nul 2>&1
if %errorlevel% neq 0 (
echo [INFO] Virtual directory "/%vdir_alias%" does not exist on "%site_name%".
echo Nothing to delete.
pause
exit /b 0
)
echo Removing virtual directory "/%vdir_alias%" from "%site_name%"...
"%appcmd%" delete vdir /vdir.name:"%site_name%/%vdir_alias%"
if %errorlevel% equ 0 (
echo [SUCCESS] Virtual directory removed from IIS configuration.
echo The physical files at the target path are NOT deleted.
) else (
echo [ERROR] Failed to delete virtual directory.
)
pause
What Gets Deleted?
Like site deletion, removing a virtual directory only removes the IIS configuration mapping. The physical files at the target path are not touched.
Virtual Directory vs. Application
IIS distinguishes between virtual directories and applications:
| Feature | Virtual Directory | Application |
|---|---|---|
| Has its own app pool? | No (inherits parent) | Yes (can have its own) |
Has its own web.config? | Yes (inherited settings) | Yes (independent) |
| Runs own .NET runtime? | No (shares parent) | Yes (isolated) |
| Created with | appcmd add vdir | appcmd add app |
Use a virtual directory when you just need a path alias to a different folder. Use an application when you need process isolation or a different .NET framework version.
Common Mistakes
The Wrong Way: Forgetting the App Name Trailing Slash
:: WRONG - Missing trailing slash in app name
"%appcmd%" add vdir /app.name:"MySite" /path:"/files" /physicalPath:"D:\Files"
The /app.name parameter requires a trailing slash for the root application. The correct format is MySite/. Without it, appcmd cannot locate the application and the command fails with an error.
The Wrong Way: Assuming Permissions Are Inherited
:: WRONG assumption - The VDIR physical path may have different ACLs
"%appcmd%" add vdir /app.name:"MySite/" /path:"/secure" /physicalPath:"E:\RestrictedData"
The physical folder's NTFS permissions are independent of IIS configuration. If the IIS worker process identity does not have read access to E:\RestrictedData, visitors will receive a 401 - Unauthorized or 500.19 error even though the virtual directory is correctly configured in IIS.
The Wrong Way: Creating a Virtual Directory Without Checking for Duplicates
:: WRONG - Running this twice produces an error
"%appcmd%" add vdir /app.name:"MySite/" /path:"/files" /physicalPath:"D:\Files"
If a virtual directory with the same path already exists, appcmd add vdir fails with an error. Always check for the existing virtual directory with appcmd list vdir /vdir.name:"SiteName/alias" before attempting creation. This makes scripts idempotent and safe to re-run.
Best Practices
- Verify the physical path exists: Always validate that the target directory exists before configuring the virtual directory. For UNC paths, warn the user if the path is unreachable but allow creation since the share may become available later.
- Check NTFS permissions: Ensure the IIS worker process identity has at least Read access to the physical folder.
- Use domain accounts for UNC paths: When pointing to network shares, configure the pool identity or "Connect As" credentials appropriately. Never hardcode passwords in script files.
- Choose virtual directories over applications: For simple path aliasing, virtual directories are lighter weight and simpler to manage. Use applications only when you need process isolation or a different .NET runtime.
- Check for existing virtual directories: Always verify a virtual directory does not already exist before attempting to create one, making scripts idempotent and safe to re-run.
- Verify
appcmd.exeand the target site exist: Check for both the tool and the target site at the start of every script to provide clear error messages. - Use
for /f "delims="with/text:for property queries: When querying virtual directory properties, use the/text:flag for clean output anddelims=to capture values including spaces.
Conclusion
Creating virtual directories in IIS from a Batch Script is a single appcmd add vdir command that maps a URL path alias to any physical folder on the server or network. This powerful feature enables flexible content organization across multiple storage locations without restructuring the website's directory hierarchy. By combining virtual directories with proper NTFS permissions and credential configuration, administrators can build sophisticated content-serving architectures that cleanly separate storage concerns from URL design.