29

I'm currently working on a deployment script that will take my site, export it from svn, remove any testing files etc in it, minify the javascript/css, copy the code to a remote web server, and then switch the physical path of the existing site to the new directory.

So far I have everything working except for switching the physical directory in IIS.

$IIsServer = Get-WmiObject Site -Namespace "root/WebAdministration" -ComputerName $serverIP -Credential $credentials -Authentication PacketPrivacy
$site = $IIsServer | Where-Object {$_.Name -eq $siteName}

When I look into the values I have I cant find the physical path property.

Any suggestions would be greatly appreciated.

Ryan French
  • 1,245
  • 3
  • 19
  • 34
  • Are both machines in Active Directory? – Kev Oct 14 '10 at 23:50
  • The machines are on different domains in Active Directory but if required we can change it so we run the script on the web server rather that on our local dev machines. – Ryan French Oct 15 '10 at 01:44

3 Answers3

53

This also works:

PS IIS:\Sites> Set-ItemProperty IIS:\Sites\Staging `
                   -name physicalPath `
                   -value "C:\blah\Web"

(Note the use of backticks for line continuations)

Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380
Doug
  • 32,844
  • 38
  • 166
  • 222
  • 1
    Note that IIS Manager may not notice the change until you either IISRESET or restart IIS Manager. – Roger Lipscombe Nov 14 '12 at 15:05
  • 11
    He will need to have `Import-Module WebAdministration` first for this to work. – jishi Apr 04 '13 at 13:25
  • 4
    I didn't need to restart IIS 7.5 for the changes to be detected. – Castrohenge Oct 01 '14 at 13:18
  • 5
    Really strange.... It seems PS v2 allows for PhysicalPath and physicalPath whereas PS v4 only allows physicalPath as the -name parameter. – Rod Hartzell Jan 05 '16 at 22:16
  • 1
    I can confirm that you do not need to reset IIS for this change to be detected. If you have IIS Manager opened, you will need to close it and open it again to see the change. As far as the site is concerned, the physical path will be changed immediately after running this command – ShaneC Jun 27 '18 at 11:25
  • You cant test if `Import-Module WebAdministration` works by trying `cd IIS:\` – Kellen Stuart Nov 10 '20 at 01:30
24

The problem with the root/WebAdministration WMI provider is that it's not very feature rich.

What you can do is use the Microsoft.Web.Administration managed API instead. This script will work if run on the server itself.

[Void][Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")

$siteName = "Default Web Site"
$serverIP = "your ip address"
$newPath = "your new path"

$serverManager = New-Object Microsoft.Web.Administration.ServerManager
## $serverManager = [Microsoft.Web.Administration.ServerManager]::OpenRemote($serverIP)
$site = $serverManager.Sites | where { $_.Name -eq $siteName }
$rootApp = $site.Applications | where { $_.Path -eq "/" }
$rootVdir = $rootApp.VirtualDirectories | where { $_.Path -eq "/" }
$rootVdir.PhysicalPath = $newPath
$serverManager.CommitChanges()

You'll notice there's a commented out line which might work for you if you need to do this remotely:

## $serverManager = [Microsoft.Web.Administration.ServerManager]::OpenRemote($serverIP)

Unfortunately MS didn't think to provide a way to supply credentials. This would mean that the account running the script would need all the right permissions granted on the remote server. I can't try this right now because I'm not near an AD environment.

The script itself will update the site root physical path (/).

For more info about IIS7's configuration see the following link:

IIS7 Configuration Reference > system.applicationHost

Kev
  • 118,037
  • 53
  • 300
  • 385
  • Thank you. I'm pretty new to Powershell and scripting IIS, and had been banging my head against the wall for a couple of days with this. – Ryan French Oct 15 '10 at 22:00
  • This helped me a lot, thanks! but in my version of Microsoft.Web.Administration OpenRemote is static which leads me to $serverManager = [Microsoft.Web.Administration.ServerManager]::OpenRemote($serverIP) – Mikael Lundin Sep 15 '11 at 14:04
  • @mikael - you are absolutely correct, I have updated my answer. Thanks! – Kev Sep 15 '11 at 14:07
  • If you have IIS Express installed, you need to specify the version of the library to load. 7.0.0.0 for full IIS and 7.9.0.0 for IIS Express. http://stackoverflow.com/q/25812169/247702 – user247702 Sep 15 '14 at 07:25
3

I'd like to build on top of @Kev's post.

You can use his method locally, but as he says there's no real way of providing credentials for his commented-out method of remotely connecting:

$serverManager = [Microsoft.Web.Administration.ServerManager]::OpenRemote($serverIP)

To change the physical path remotely, with credentials, use the following:

#configure your remote credentials
$computerName = "remotehostname"
$securePassword = ConvertTo-SecureString "password" -AsPlainText -force
$credential = New-Object System.Management.Automation.PsCredential("username", $securePassword)

#remove –SkipCACheck –SkipCNCheck –SkipRevocationCheck if you don't have any SSL problems when connecting
$options = New-PSSessionOption –SkipCACheck –SkipCNCheck –SkipRevocationCheck
$session = New-PSSession -ComputerName $computerName -Authentication Basic -Credential $credential -UseSSL -SessionOption $options

$block = {
    [Void][Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")

    $siteName = "Default Web Site"
    $serverIP = "your ip address"
    $newPath = "your new path"

    $serverManager = New-Object Microsoft.Web.Administration.ServerManager
    $site = $serverManager.Sites | where { $_.Name -eq $siteName }
    $rootApp = $site.Applications | where { $_.Path -eq "/" }
    $rootVdir = $rootApp.VirtualDirectories | where { $_.Path -eq "/" }
    $rootVdir.PhysicalPath = $newPath
    $serverManager.CommitChanges()
}

#run the code in $block on your remote server via the $session var
Invoke-Command -Session $session -ScriptBlock $block

Note: For remote PowerShell scripting, ensure TCP ports 5985 and 5986 are open outbound on your local network and inbound on your remote server.

Community
  • 1
  • 1
theyetiman
  • 8,514
  • 2
  • 32
  • 41