User Guide

Updating Ouvvi via Powershell

If you are running an Ouvvi on an older server that doesn't support the deployment manager then you can manually run the powershell script to update your Ouvvi tenant.

To do this open PowerShell ISE as an administrator, and open a new file. Enter in the script below but change the targetPath to match your tenant path at the very end of the script.

Usually you can find your tenant in the C drive under the Ouvvi Tenants folder, but if you changed this location at the point of installation you can find it by using IIS Manager.

To find the tenant location in IIS, go to Sites and right click onto the Ouvvi tenant. Then go to Manage Sites > Advanced Settings.

This will open a window where you can find the physical path to the tenant. It will show the full path into the web folder, but you only need the root i.e. C:\OuvviTenants\Default

Ouvvi Tenant Path

Import-Module WebAdministration

function Install-OuvviSqlExpress {
    [CmdletBinding()]
    param(
        [string] $targetPath = "C:\OuvviTenants\Default",
        [string] $iisAppPoolName = "OuvviDefault",
        [string] $iisAppName = "OuvviDefault",
        [string] $iisPortNumber = "8080",
        [string] $instanceName = "Default",
		[string] $serviceUserName = "NT AUTHORITY\NETWORK SERVICE",
        [string] $servicePassword = "password"
		) 
		BEGIN {
        
			$sourceDir = Join-Path -Path $Env:DATASYNCINSTALLPATH -ChildPath "Ouvvi"

			if(Test-Path -Path $targetPath)
			{
                $sourceDir = Join-Path -Path $Env:DATASYNCINSTALLPATH -ChildPath "Ouvvi\*"
            }
			
			Copy-Item $sourceDir $targetPath -recurse
        
			Set-Location $targetPath

			$webPath = Join-Path -Path $targetPath -ChildPath "Web"
			$webConfig = $webPath + "\Web.config"
			$servicePath =  Join-Path -Path $targetPath -ChildPath "Service\Simego.Console.Service.exe"
			$serviceConfig = $servicePath + ".config"

			$url = "http://localhost:" + $iisPortNumber

			#navigate to the app pools root
			Set-Location IIS:\AppPools\

			$appPool = New-Item $iisAppPoolName
			$appPool | Set-ItemProperty -Name "managedRuntimeVersion" -Value "v4.0"
			$appPool | Set-ItemProperty -Name "processModel.loadUserProfile" -Value true
			$appPool | Set-ItemProperty -Name "processModel.identityType" -Value 2

			#navigate to the sites root
			Set-Location IIS:\Sites\

			$iisApp = New-Item $iisAppName -bindings @{protocol="http";bindingInformation=":" + $iisPortNumber + ":"} -physicalPath $webPath
			$iisApp | Set-ItemProperty -Name "applicationPool" -Value $iisAppPoolName
			
			# Update Authentication
			Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/AnonymousAuthentication -name enabled -value false -location $iisAppName
			Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/windowsAuthentication -name enabled -value true -location $iisAppName
			Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/basicAuthentication -name enabled -value false -location $iisAppName

			# Install the Ouvvi Service
			$credentialsPassword = ConvertTo-SecureString $servicePassword -AsPlainText -Force
			$credentials = New-Object System.Management.Automation.PSCredential ($serviceUserName, $credentialsPassword)
			$serviceName = "Ouvvi$instanceName"
			$serviceDisplayName = "Ouvvi Processing Service ($instanceName)"
			$serviceDescription = "The Ouvvi Processing Service for Instance $instanceName."

			New-Service -Name $serviceName -BinaryPathName $servicePath -DisplayName $serviceDisplayName -StartupType Manual -Description $serviceDescription -Credential $credentials

			# Generate a Random Message Signature Key
			$messageKey = -join ((48..57) + (65..90) + (97..122) | Get-Random -count 50 | ForEach-Object {[char]$_})

			$connectionString = "data source=.\SQLEXPRESS;initial catalog=Ouvvi$instanceName;integrated security=true;"

			# Update the Service Endpoint address
			# Update the MessageSignatureKey
			$xdoc = new-object System.Xml.XmlDocument
			$xdoc.load($serviceConfig)
			$xdoc.SelectSingleNode("/configuration/appSettings/add[@key='OuvviServiceUrl']").Attributes["value"].Value = $url
			$xdoc.SelectSingleNode("/configuration/appSettings/add[@key='MessageSignatureKey']").Attributes["value"].Value = $messageKey        
			$xdoc.Save($serviceConfig)

			# Update the MessageSignatureKey in Web.Config
			$xdoc = new-object System.Xml.XmlDocument
			$xdoc.load($webConfig)
			$xdoc.SelectSingleNode("/configuration/appSettings/add[@key='MessageSignatureKey']").Attributes["value"].Value = $messageKey        
			$xdoc.SelectSingleNode("/configuration/connectionStrings/add[@name='DefaultConnection']").Attributes["connectionString"].Value = $connectionString        
			$xdoc.Save($webConfig)

			$sqlcommands = ("IF NOT(EXISTS(select * from sys.syslogins WHERE [Name] = 'NT AUTHORITY\NETWORK SERVICE')) CREATE LOGIN [NT AUTHORITY\NETWORK SERVICE] FROM WINDOWS WITH DEFAULT_DATABASE=[master]","IF NOT(EXISTS(select * from sys.sysdatabases WHERE [Name] = 'Ouvvi$instanceName')) CREATE DATABASE [Ouvvi$instanceName]", "USE [Ouvvi$instanceName]", "CREATE USER [NT AUTHORITY\NETWORK SERVICE] FOR LOGIN [NT AUTHORITY\NETWORK SERVICE]", "ALTER ROLE [db_owner] ADD MEMBER [NT AUTHORITY\NETWORK SERVICE]")

			$connection = New-Object System.Data.SqlClient.SqlConnection("data source=.\SQLEXPRESS;initial catalog=master;integrated security=true;")
			$connection.Open()

			foreach($command in $sqlcommands)
			{
				$cmd = New-Object System.Data.SqlClient.SqlCommand($command, $connection)
				$cmd.ExecuteNonQuery()
			}

			return $url
		}
	}

	function Update-Ouvvi {
		[CmdletBinding()]
		param(
			[string] $targetPath = "C:\OuvviTenants\Default",
			[string] $serviceName = "Ouvvi*"
			) 
		BEGIN {
        
			$service = Get-Service -Name $serviceName | Where-Object -Property Status -Value Running -EQ
			if($service)
			{
				Throw "Please Stop Ouvvi Service(s) before updating"				
			}
			
			$sourceDir = Join-Path -Path $Env:DATASYNCINSTALLPATH -ChildPath "Ouvvi" 
												
			Write-Verbose "Deleting Web Files from bin,Content,fonts,scripts and Views folders."				
			Remove-Item -Path (Join-Path -Path $targetPath -ChildPath "Web\bin\*") -Recurse
			Remove-Item -Path (Join-Path -Path $targetPath -ChildPath "Web\Content\*") -Recurse
			Remove-Item -Path (Join-Path -Path $targetPath -ChildPath "Web\Scripts\*") -Recurse
			Remove-Item -Path (Join-Path -Path $targetPath -ChildPath "Web\Views\*") -Recurse -ErrorAction SilentlyContinue
			
			
			Write-Verbose "Updating Folder $sourceDir"				
			
			Copy-Item -Path (Join-Path -Path $targetPath -ChildPath "Web\Web.config") -Destination (Join-Path -Path $targetPath -ChildPath "Web\Web.config.copy") -Force
			Copy-Item -Path (Join-Path -Path $targetPath -ChildPath "Service\Simego.Console.Service.exe.config") -Destination (Join-Path -Path $targetPath -ChildPath "Service\Simego.Console.Service.exe.config.copy") -Force
 
			Get-ChildItem -Path $sourceDir | ForEach-Object { Copy-Item -Path $_.FullName -Destination $targetPath -Recurse -force }

			Copy-Item -Path (Join-Path -Path $targetPath -ChildPath "Web\Web.config.copy") -Destination (Join-Path -Path $targetPath -ChildPath "Web\Web.config") -Force
			Copy-Item -Path (Join-Path -Path $targetPath -ChildPath "Service\Simego.Console.Service.exe.config.copy") -Destination (Join-Path -Path $targetPath -ChildPath "Service\Simego.Console.Service.exe.config") -Force

			Remove-Item -Path (Join-Path -Path $targetPath -ChildPath "Web\Web.config.copy")
			Remove-Item -Path (Join-Path -Path $targetPath -ChildPath "Service\Simego.Console.Service.exe.config.copy")			

			$webPath = Join-Path -Path $targetPath -ChildPath "Web"
			$webConfig = $webPath + "\Web.config"
			if(Test-Path -Path $webConfig)
			{
				$sourceWebConfig = Join-Path -Path $sourceDir -ChildPath "Web\Web.Config"
				
				$xsourcedoc = new-object System.Xml.XmlDocument
				$xsourcedoc.load($sourceWebConfig)
				$xsourcedocnsmgr = new-object System.Xml.XmlNamespaceManager($xsourcedoc.NameTable)

				$xsourcedocnsmgr.AddNamespace("ns1", "urn:schemas-microsoft-com:asm.v1")

				$assemblynode = $xsourcedoc.SelectSingleNode("/configuration/runtime/ns1:assemblyBinding/ns1:dependentAssembly/ns1:assemblyIdentity[@name='Simego.DataSync']", $xsourcedocnsmgr) 
				if($assemblynode)
				{
					$assemblynode = $assemblynode.ParentNode.SelectNodes("ns1:bindingRedirect", $xsourcedocnsmgr)
				
					if($assemblynode)
					{
						$dspath = Join-Path -Path $Env:DATASYNCINSTALLPATH -ChildPath "Simego.DataSync.dll"	
						$assembly = [Reflection.Assembly]::Loadfile($dspath)
						$assemblyVersion = $assembly.GetName().Version.ToString(4)

						$assemblynode.Attributes[0].InnerText = "0.0.0.0-$assemblyVersion"
						$assemblynode.Attributes[1].InnerText = "$assemblyVersion"
					}
				}

				$sourceAssemblynode = $xsourcedoc.SelectSingleNode("/configuration/runtime/ns1:assemblyBinding", $xsourcedocnsmgr)

				Write-Host "Updating $webConfig"

				$xdoc = new-object System.Xml.XmlDocument
				$xdoc.load($webConfig)
				$nsmgr = new-object System.Xml.XmlNamespaceManager($xdoc.NameTable)

				$nsmgr.AddNamespace("ns1", "urn:schemas-microsoft-com:asm.v1")

				$assemblynode = $xdoc.SelectSingleNode("/configuration/runtime/ns1:assemblyBinding", $nsmgr) 
				if($assemblynode)
				{					
					$assemblynode.InnerXml = $sourceAssemblynode.InnerXml						
				}

				$xdoc.Save($webConfig)				
			}

			$servicePath = Join-Path -Path $targetPath -ChildPath "Service"
			$serviceConfig = $servicePath + "\Simego.Console.Service.exe.config"
			if(Test-Path -Path $serviceConfig)
			{
				$sourceServiceConfig = Join-Path -Path $sourceDir -ChildPath "Service\Simego.Console.Service.exe.config"
				
				$xsourcedoc = new-object System.Xml.XmlDocument
				$xsourcedoc.load($sourceServiceConfig)
				$xsourcedocnsmgr = new-object System.Xml.XmlNamespaceManager($xsourcedoc.NameTable)

				$xsourcedocnsmgr.AddNamespace("ns1", "urn:schemas-microsoft-com:asm.v1")

				$assemblynode = $xsourcedoc.SelectSingleNode("/configuration/runtime/ns1:assemblyBinding/ns1:dependentAssembly/ns1:assemblyIdentity[@name='Simego.DataSync']", $xsourcedocnsmgr) 
				if($assemblynode)
				{
					$assemblynode = $assemblynode.ParentNode.SelectNodes("ns1:bindingRedirect", $xsourcedocnsmgr)
				
					if($assemblynode)
					{
						$dspath = Join-Path -Path $Env:DATASYNCINSTALLPATH -ChildPath "Simego.DataSync.dll"	
						$assembly = [Reflection.Assembly]::Loadfile($dspath)
						$assemblyVersion = $assembly.GetName().Version.ToString(4)

						$assemblynode.Attributes[0].InnerText = "0.0.0.0-$assemblyVersion"
						$assemblynode.Attributes[1].InnerText = "$assemblyVersion"
					}
				}

				$sourceAssemblynode = $xsourcedoc.SelectSingleNode("/configuration/runtime/ns1:assemblyBinding", $xsourcedocnsmgr)

				Write-Host "Updating $serviceConfig"

				$xdoc = new-object System.Xml.XmlDocument
				$xdoc.load($serviceConfig)
				$nsmgr = new-object System.Xml.XmlNamespaceManager($xdoc.NameTable)

				$nsmgr.AddNamespace("ns1", "urn:schemas-microsoft-com:asm.v1")

				$assemblynode = $xdoc.SelectSingleNode("/configuration/runtime/ns1:assemblyBinding", $nsmgr) 
				if($assemblynode)
				{					
					$assemblynode.InnerXml = $sourceAssemblynode.InnerXml						
				}

				$xdoc.Save($serviceConfig)				
			}

		}
	}

	function Install-OuvviUpgrade {
		[CmdletBinding()]
		param(
			[string] $targetPath = "C:\OuvviTenants\Default",
			[string] $serviceName = "Ouvvi*",
			[string] $url = "http://localhost:8080"
			) 
		BEGIN {
        
			$sourceDir = Join-Path -Path $Env:DATASYNCINSTALLPATH -ChildPath "Ouvvi" 
			
			$webPath = Join-Path -Path $targetPath -ChildPath "Web"
			$webConfig = $webPath + "\Web.config"
			$servicePath =  Join-Path -Path $targetPath -ChildPath "Service\Simego.Console.Service.exe"
			$serviceConfig = $servicePath + ".config"

			$service = Get-Service -Name $serviceName | Where-Object -Property Status -Value Running -EQ
			if($service)
			{
				Throw "Please Stop Ouvvi Service(s) before upgrading"				
			}
			
			if(Test-Path -Path $webPath)
			{
				Write-Verbose "Removing Web Folder Contents $webPath"
				Get-ChildItem -Path $webPath | ForEach-Object { Remove-Item -Path $_.FullName -Recurse -force }
			}
			
			Write-Verbose "Updating Folder $targetPath"				
			Get-ChildItem -Path $sourceDir | ForEach-Object { Copy-Item -Path $_.FullName -Destination $targetPath -Recurse -force }

			$dataSyncPath = Join-Path -Path $targetPath -ChildPath "DataSync"
			if(Test-Path -Path $dataSyncPath)
			{
				Write-Verbose "Removing Folder $dataSyncPath"
				Remove-Item -Path $dataSyncPath -Recurse -Force
			}
			
			$logPath = Join-Path -Path $targetPath -ChildPath "Logs"
			if(Test-Path -Path $logPath)
			{
				Write-Verbose "Removing Folder $logPath"
				Remove-Item -Path $logPath -Recurse -Force
			}

			$ouvviConfig = Join-Path -Path $targetPath -ChildPath "Ouvvi.config"
			if(-Not (Test-Path -Path $ouvviConfig))
			{
				$ouvviGlobalConfig = Join-Path -Path $env:ProgramData -ChildPath "Simego\Ouvvi\Ouvvi.config"
				Write-Verbose "Checking for Global Ouvvi.config $ouvviGlobalConfig"
				if(Test-Path -Path $ouvviGlobalConfig)
				{
					$ouvviConfig = $ouvviGlobalConfig
				}			
			}
						
			if(Test-Path -Path $ouvviConfig)
			{
				Write-Verbose "Migrate Ouvvi DB Settings to $ouvviConfig"

				# Generate a Random Message Signature Key
				$messageKey = -join ((48..57) + (65..90) + (97..122) | Get-Random -count 50 | ForEach-Object {[char]$_})
	
				$xdoc = new-object System.Xml.XmlDocument
				$xdoc.load($ouvviConfig)
				$connectionString = $xdoc.SelectSingleNode("/configuration/connectionStrings/add[@name='ConsoleDB']").Attributes["connectionString"].Value

				$xdoc = new-object System.Xml.XmlDocument
				$xdoc.load($webConfig)
				$xdoc.SelectSingleNode("/configuration/appSettings/add[@key='MessageSignatureKey']").Attributes["value"].Value = $messageKey        		
				$xdoc.SelectSingleNode("/configuration/connectionStrings/add[@name='DefaultConnection']").Attributes["connectionString"].Value = $connectionString        
				$xdoc.Save($webConfig)

				Write-Verbose "Migrate Ouvvi Service Settings to $serviceConfig"

				$xdoc = new-object System.Xml.XmlDocument
				$xdoc.load($serviceConfig)
				$xdoc.SelectSingleNode("/configuration/appSettings/add[@key='OuvviServiceUrl']").Attributes["value"].Value = $url
				$xdoc.SelectSingleNode("/configuration/appSettings/add[@key='MessageSignatureKey']").Attributes["value"].Value = $messageKey        
				$xdoc.Save($serviceConfig)				
			}
		}
	}

	function Set-OuvviDBUserDBOwner {
		[CmdletBinding()]
		param(
			[string] $targetPath = "C:\OuvviTenants\Default",
			[string] $userName = "NT AUTHORITY\NETWORK SERVICE"
			) 
		BEGIN {
			
			[System.Reflection.Assembly]::LoadWithPartialName('System.Data')

			$webPath = Join-Path -Path $targetPath -ChildPath "Web"
			$webConfig = $webPath + "\Web.config"

			$xdoc = new-object System.Xml.XmlDocument
			$xdoc.load($webConfig)
			$connectionString = $xdoc.SelectSingleNode("/configuration/connectionStrings/add[@name='DefaultConnection']").Attributes["connectionString"].Value
						
			$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
			$connection.Open()
			$cmd = New-Object System.Data.SqlClient.SqlCommand("exec sp_addrolemember 'db_owner', '$userName'", $connection)
			$cmd.ExecuteNonQuery()
		}
	}

Update-Ouvvi -targetPath C:\OuvviTenants\Default