Make a local copy of your live DNN installation

copy dnn Inspired by a blog post from Bruce Chapman (iFinity) I built 2 powershell scripts that do (most of) the needed steps by starting a simple script. But before we take a closer look on the scripts lets talk a little bit about my setup.

  1. ) My customer websites on the server reside in a folder named customernumber_customername (e.g. 0000_bitboxx). In this folder I have a subfolder called “dnn” where the DNN installation is found. This gives me the opportunity to have other functionality installed for this customer in his home folder (e.g. “webmail”)
  2. ) Locally I have a virtual machine set up with all the developer and debugging stuff I need (VS, Resharper, Fiddler ..).  And also all the stuff I need to run a DotNetNuke website (IIS, SQLServer)
  3. ) On the webserver, I need to install the Powershell Community Extensions found on Codeplex. This is only needed for zipping the website files and the backup of the database. If someone finds a better solution (with 7zip and command line parameters for example) please let me know!
  4. ) In my virtual machine I have an SQL User named “test” that I use in the local web.config  for the copied website. The script adds this user automatically to the database and changes the appropriate line in web.config
  5. ) In opposite to Bruce Chapman I don’t change the domain of the installation. The script adds the domain to the host-file in the virtual machine. So running it in the VM ensures that you do not hassle with your live site. (If you want to be sure sure: disconnect the VM from the internet connection!)

If you never have worked with powershell before (as me a few days before), you need to know a few things. Normally powershell is installed on your windows machine. The version does not matter for my scripts. But before  you can start with them you need to set the permission. By default running scripts is prohibited in windows security. So open up a powershell window as administrator and enter the following :

Set-ExecutionPolicy RemoteSigned

Now lets start with the backup script for the server:

The backup script

# Configure these
$DBName = "0006_bitboxx"
$DNNInstallPath = "D:\0006_bitboxx\dnn"
$OutPutPath = "D:\temp\backup\"
$SqlInstance = "MSSQLINSTANCE"

# Here we go...
$DNNZipFile = $DBName + ".dnn.zip"
$DBZipFile = $DBName + ".db.zip"
$ResZipFile = $DBName +".zip"
$DNNZipName = $OutPutPath + $DNNZipFile

# Clear screen

#zip DNN to Targetdirectory
write-host "Zip DNN ..."
$dummy=Write-Zip -level 9 -IncludeEmptyDirectories -Path $DNNInstallPath -OutputPath $DNNZipName -Quiet

write-host "Backup DB ..."
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
$s = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $SqlInstance
$DBBakFile = $OutPutPath + $DBName + ".bak"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SmoExtended') | out-null
$dbBackup = new-object ("Microsoft.SqlServer.Management.Smo.Backup")
$dbBackup.Database = $DBName
$dbBackup.Devices.AddDevice($DBBakFile, "File") 
$dbBackup.Action = "Database"

write-host "Zip DB ..."
$DBZipName = $OutPutPath + $DBZipFile
$dummy = Write-Zip -level 9 $DBBakFile -OutputPath $DBZipName -Quiet 

write-host "Clean up ..."
$dummy=Remove-Item $DBBakFile

write-host "Ready ! See files ($DBZipFile, $DNNZipFile) in $OutPutPath" 

So, whats happening here ? At first, we need to configure some things in the first 4 lines like Database name, Path to DNN installation, Path to the resulting zip files and the name of your SQL server instance. The line which begins with $dummy = write-zip  only functions if the powershell community extensions are installed. This command has the backdraft that it retains the directory structure in the zip only if you enter a dirctory (here $DNNInstallPath) as a parameter.  Keep that in mind if you want to alter the script for your needs! Next we use the SMO to backup our database and after that we zip the resulting bak file too into our $OutPutPath. Last we delete the .bak file and end up with two zips: “0006_bitboxx.dnn.zip” which contains the DNN files and “0006_bitboxx.db.zip” which contains the backup of the database.

Download the zips

Sorry, no script for this… Do it the way you prefer :-)

The restore script

This one is a little bit more difficult and costs my a few grey hairs (more). But for me its running now perfectly. Tried to get the restore process of the database done with SMO too, but this does not work for me in some circumstances (don’t no which and why). So plain old SQL does the job ^^

# Configure these 
$DBName = "0006_bitboxx"
$WebSiteAddress = "www.bitboxx.net"
$SqlInstance = "TW-WIN8-DEVWEB"
$frameworkRuntime = "v4.0" # "v2.0" oder "v4.0"
$InPutPath = "C:\Temp\Backup\"
$WebSitePath = "C:\Inetpub\wwwroot\$DBName\dnn\"
$OutPutPath = "C:\Inetpub\wwwroot\$DBName\"

# Here we go
$DNNZipFile = $DBName + ".dnn.zip"
$DBZipFile = $DBName + ".db.zip"
$LocalDBUser = "test"
$connectionString = "Data Source=$SqlInstance;Initial Catalog=$DBName;User ID=$LocalDBUser;Password=$LocalDBUser" 
$WebsiteName = $DBName
$DNNZipPath = $InPutPath + $DNNZipFile
$DBZipPath = $InPutPath + $DBZipFile

Import-Module WebAdministration

#remove existing IIS Site and App pool
write-host "Remove old website information in IIS (if any)..."
Remove-Item IIS:\Sites\$websiteName -Recurse -ErrorAction SilentlyContinue
Remove-Item IIS:\AppPools\$websiteName -Recurse -ErrorAction SilentlyContinue

#delete anything in the destination folder
write-host "Delete old contents of target directory (if any)..."
$dummy = new-item -force -path $OutPutPath -itemtype "directory"
$dummy = get-childitem $OutPutPath | remove-item -force -recurse

#unzip DNN to Targetdirectory
$Shell = New-Object -ComObject Shell.Application
$Dest = $Shell.namespace($OutPutPath)
$Zip = $Shell.namespace($DNNZipPath)
write-host "Unzip DNN Files..."

#Set the ACL on the folder
write-host "Adding 'FullControl' to website folder ..."
$Acl = Get-Acl $OutPutPath
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("NETZWERKDIENST", "FullControl", $inherit, $propagation, "Allow")
$dummy = Set-Acl -AclObject $Acl $OutPutPath
Write-Host "'Fullcontrol' access was added to $OutPutPath"

#Create the IIS Site and App pool
$dummy = New-Item IIS:\AppPools\$WebsiteName -Force
$dummy = Set-ItemProperty IIS:\AppPools\$WebsiteName -name ProcessModel.identityType -Value 2
$dummy = Set-ItemProperty IIS:\AppPools\$WebsiteName managedRuntimeVersion $frameworkRuntime
$dummy = New-Item IIS:\Sites\$WebsiteName -bindings @{protocol="http";bindingInformation=":80:$WebsiteAddress"} -physicalPath $WebSitePath
$dummy = Set-ItemProperty IIS:\Sites\$WebsiteName -name applicationPool -value $WebsiteName
write-host "Webside + Applicationpool for $WebsiteName created"

#Update the hosts file
$hostsentry = Select-String $Env:SystemRoot\System32\drivers\etc\hosts -pattern "$WebsiteAddress" -quiet
if (-not $hostsentry)
    Add-Content $Env:SystemRoot\System32\drivers\etc\hosts "        $WebsiteAddress"
    write-host "Added $WebsiteAddress to hosts file"

#Unzip DB.bak 
$Shell = New-Object -ComObject Shell.Application
$Dest = $Shell.namespace($InPutPath)
$Zip = $Shell.namespace($DBZipPath)
write-host "Unzip DB File..."

#Restore the database
#load assembly
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"

#need to check if database exists, and if it does, drop it
$db = $server.Databases[$DBName]
if ($db)
      #we will use KillDatabase instead of Drop
      #Kill database will drop active connections before 
      #dropping the database
      write-host "Database $DBName exists, will be deleted now!"

#get backup file
$backupFile = $InputPath + $DBName + ".bak"

# Open ADO.NET Connection with Windows authentification to local $SqlInstance.
$con = New-Object Data.SqlClient.SqlConnection;
$con.ConnectionString = "Data Source=" + $SqlInstance + ";Initial Catalog=master;Integrated Security=True;";

# Create the database.
$sql = "CREATE DATABASE [$DBName];"
$cmd = New-Object Data.SqlClient.SqlCommand $sql, $con;
$dummy = $cmd.ExecuteNonQuery();		
Write-Host "Database $DBName is created!";

# DB Filename + Logfilename shortening (RESTORE DATABASE MOVE syntax ...)
$moveDB = $DBName
if ($moveDB.Length -gt 16)
   $moveDB = $moveDB.Substring(0,16)
$moveDBLog = ($DBName + "_log")
if ($moveDBLog.Length -gt 20)
   $moveDBLog = $moveDBLog.Substring(0,20)

Write-Host "Restoring Database $DBName ...";
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$db = $server.Databases[$DBName]
$DBMasterPath = $db.PrimaryFilePath

$sql = "USE [master]; RESTORE DATABASE [" + $DBName + "] FROM  DISK = N'" + $backupFile+ "' WITH  FILE = 1,  MOVE N'"+ $moveDB + "' TO N'" + $DBMasterPath + $DBName +".mdf',  MOVE N'" + $moveDBLog + "' TO N'"+ $DBMasterPath + $DBName+ "_log.ldf',  NOUNLOAD,  REPLACE,  STATS = 5"
$cmd = New-Object Data.SqlClient.SqlCommand $sql, $con;
$dummy = $cmd.ExecuteNonQuery();		
Write-Host "Database $DBName is Restored!";

remove-item $backupFile

# Adding "test" user to the database and make him dbowner
$sql = "USE [$dbname]"
$cmd = New-Object Data.SqlClient.SqlCommand $sql, $con;
$dummy = $cmd.ExecuteNonQuery();
$sql = "CREATE USER [$LocalDBUser] FOR LOGIN [$LocalDBUser]"
$cmd = New-Object Data.SqlClient.SqlCommand $sql, $con;
$dummy = $cmd.ExecuteNonQuery();
$sql = "EXEC sp_addrolemember N'db_owner', N'$LocalDBUser'"
$cmd = New-Object Data.SqlClient.SqlCommand $sql, $con;
$dummy = $cmd.ExecuteNonQuery();
Write-Host "Made User '$LocalDBUser' dbowner!";

# Close & Clear all ADO things.

# Change web.config connection string
write-host "Change connectionstring in web.config..."
$webConfigPath = $WebSitePath +"web.config"
$backup = $webConfigPath + ".bak"

# Get the content of the config file and cast it to XML and save a backup copy labeled .bak 
$xml = [xml](get-content $webConfigPath)

# Change original connectionString
$root = $xml.get_DocumentElement();
$node = $root.SelectSingleNode("//connectionStrings/add[@name='SiteSqlServer']")
$node.connectionString = $connectionString

# Save it
write-host "Restore Done!"

Hope these scripts can speed up your admin or developer life and frees you up from doing daunting tasks! And if you have any suggestions or better solutions, please let me know !

Total: 15 Comment(s)
To make a live installation you need to go to https://topamericanwriters.com/dissertationteam-com-review/ and then try it again. It'll work for sure as it worked on my computer too.
Sunday, October 14, 2018 · reply ·
pexe jurer
Thanks for sharing the information. Keep the good work going. https://kinguser.xyz/apk/">kinguser https://poweramp.pro/apk/">Poweramp https://leoplaycard.xyz/apk/">leo playcard
Wednesday, November 14, 2018 · reply ·
You guys are missing so many things here that only you can work on and you can see that htings here are only going to work on internet marketing services company. If there's something that I can help you with, I will try for sure. https://www.marketing1on1.com/">strategic internet marketing services
Saturday, December 15, 2018 · reply ·
Buy Adsense safe Traffic
You need to join in a contest first of the finest blogs on the web. I most certainly will suggest this site!
Monday, December 17, 2018 · reply ·
Giving thanks for your write-up. I know that with today’s complicated world, folks have many beliefs and this has made it to be really hard for learners just like me. However, you have made the idea very easy for me to fully grasp and I now have the awareness of the correct thing. Your own continued reputation as among the top experts about this topic may be boosted through words associated with appreciation from subscribers like me. Thanks, once more. https://www.rahaanairobi.com">Nairobi raha girls
Wednesday, December 19, 2018 · reply ·
Fishing Resorts in Northern Minnesota
You created some decent points there. I looked online with the issue and located most individuals goes in addition to using your site. https://www.orrpelicanlake.com/">Fishing Resorts in Northern Minnesota
Wednesday, December 19, 2018 · reply ·
Supremo Blog
This may be the right weblog for everyone who wishes to learn about this topic. https://digitalsupremo.wordpress.com">Supremo Blog
Tuesday, December 25, 2018 · reply ·
Thursday, December 27, 2018 · reply ·
Buy social Traffic
Magnificent goods from you, man. I have understand your stuff previous to and you are just extremely excellent. I really like what you’ve acquired here, certainly like what you are saying and the way in which you say it. You make it enjoyable and you still care for to keep it sensible. I can not wait to read much more from you. This is actually a wonderful web site.
Tuesday, January 8, 2019 · reply ·
This really is an incredibly amazing powerful resource that you’re offering and you just provide it away cost-free!! I comparable to discovering websites that view the particular price of providing you beautiful learning resource for zero cost. We truly dearly loved examining this web site. Be thankful! SEO https://digitalsupremo.wordpress.com
Saturday, January 12, 2019 · reply ·
I simply wanted to thank you a lot more for your amazing website you have developed here. It can be full of useful tips for those who are actually interested in this specific subject, primarily this very post. Your all so sweet in addition to thoughtful of others and reading the blog posts is a great delight in my opinion. And thats a generous present! Dan and I usually have enjoyment making use of your recommendations in what we need to do in the near future. Our checklist is a distance long and tips will certainly be put to excellent use. Marketing https://clickate.com/
Sunday, January 13, 2019 · reply ·
Poonam Kumari
Tuesday, April 9, 2019 · reply ·
Quickbooks Tech Support
Students may also have to obtain piracy problems on some third parties suppliers. Escaping these problems students should take expert guidance before purchasing this system. As well as they should analyze all the main reasons of purchasing QuickBooks bookkeeping system from any third party system source. http://www.advisorexpert.co.uk/quickbooks-support-phone-number/
Monday, April 22, 2019 · reply ·
Lucy Gray
Packers and Movers Bangalore are running in relocation field from coon’s age and serving us with the help of highly professional and trained team and to make our relocation more effective and efficient they are loaded with updated relocation equipment and techniques. Packers and Movers Bangalore is from 4 elite moving company and certified with IBA for relocation work. Packers and Movers Bangalore #charges are reasonable and genuine and because of this quality they also are known as #cheap and #best Packers and Movers in Bangalore. Packers and Movers Bangalore carries almost all kind of relocation for that they have a different team who are specialized and experienced in their respective fields. https://assuremoving.in/packers-and-movers-mumbai/
Tuesday, April 30, 2019 · reply ·
David Harry
Avira Lab experts developed the following malware examine out functions for all users: Full Scan: Full examine out is a finish examine out of the whole pc. The Avira anti-virus, difficult generate drive, e-mail database, system back-up, default system memory, removable storage media, and default can examine out these following objects: system memory, weighted objects on startup, and the system generate etc. For more information : http://www.quickhelps.co/phone-number/avira/
Wednesday, May 1, 2019 · reply ·


Torsten WeggenMy name is Torsten Weggen and I am CEO of indisoftware GmbH in Hanover, Germany. I'm into DNN since 2008. Before this, I did a lot of desktop stuff mainly coded with Visual Foxpro (see http://www.auktionsbuddy.de). 

I'm programmer, husband, father + born in 1965.

Please feel free to contact me if you have questions.

Latest Posts

DNN module development with Angular 2+ (Part 7)
6/10/2018 1:43 PM | Torsten Weggen
DNN module development with AngularJS (Part 6)
12/16/2016 7:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 5)
12/16/2016 6:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 4)
12/16/2016 5:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 3)
12/16/2016 4:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 2)
12/16/2016 3:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 1)
12/15/2016 7:19 AM | Torsten Weggen
Blogging in DNN with Markdown Monster by Rick Strahl
11/27/2016 1:14 PM | Torsten Weggen
Creating a global token engine
11/18/2016 10:25 AM | Torsten Weggen
DnnImagehandler - Hot or not ?
2/21/2015 11:52 PM | Torsten Weggen

My Twitter

Torsten Weggen 3/17/2019

You can make a real difference in Abir ’s life. Join me on @Kiva https://t.co/NlCTgIAZAN

Torsten Weggen 2/2/2019

As a freelance developer I often get invites from headhunters. This one should be very interesting... https://t.co/CNrEXBTBuJ

Torsten Weggen 10/11/2018

Evernote or OneDrive user and love #markdown #markdownmonster ? Take a look at Joplin! https://t.co/4bzkiD6CHn