<# .Synopsis Common module .Description Common module to give core funtionality for IIS scaffoldong. #> #region Private variables $loggingDirectory = "C:\Temp" $loggingFile = "Install.log" $logFile = Join-Path $loggingDirectory $loggingFile #endregion #region Public methods function Backup-Database($sqlInstaceName, $databaseName, $userName, $securePassword, $backupPath) { if(!(Test-Path $backupPath)) { New-Item $backupPath -type directory } $timestamp = Get-Date -Format yyyyMMddHHmmss $credential = New-Object System.Management.Automation.PSCredential ($userName, $securePassword) Backup-SqlDatabase -ServerInstance $sqlInstaceName -Database $databaseName -BackupFile ( Join-Path $backupPath "$($databaseName)_db_$($timestamp).bak") -Verbose -Credential $credential -ErrorAction Continue } function Drop-Database($sqlInstaceName, $databaseName, $userName, $securePassword) { $server = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $sqlInstaceName $server.ConnectionContext.LoginSecure = $false $server.ConnectionContext.set_Login($userName) $server.ConnectionContext.set_SecurePassword($securePassword) $dbObject = $server.Databases[$databaseName] if ($dbObject) { $server.KillDatabase($databaseName) } } function Restore-Database($sqlInstaceName, $databaseName, $userName, $securePassword, $backupFileToRestore) { $credential = New-Object System.Management.Automation.PSCredential ($userName, $securePassword) $server = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $sqlInstaceName $server.ConnectionContext.LoginSecure = $false $server.ConnectionContext.set_Login($userName) $server.ConnectionContext.set_SecurePassword($securePassword) $dataFolder = $server.Settings.DefaultFile; $logFolder = $server.Settings.DefaultLog; if ($dataFolder.Length -eq 0) { $dataFolder = $server.Information.MasterDBPath; } if ($logFolder.Length -eq 0) { $logFolder = $server.Information.MasterDBLogPath; } $backupDeviceItem = new-object Microsoft.SqlServer.Management.Smo.BackupDeviceItem $backupFileToRestore, 'File'; $restore = new-object 'Microsoft.SqlServer.Management.Smo.Restore'; $restore.Database = $databaseName; $restore.Devices.Add($backupDeviceItem); $dataFileNumber = 0; foreach ($file in $restore.ReadFileList($server)) { $relocateFile = new-object 'Microsoft.SqlServer.Management.Smo.RelocateFile'; $relocateFile.LogicalFileName = $file.LogicalName; if ($file.Type -eq 'D'){ if($dataFileNumber -ge 1) { $suffix = "_$dataFileNumber"; } else { $suffix = $null; } $relocateFile.PhysicalFileName = "$dataFolder\$DatabaseName$suffix.mdf"; $dataFileNumber ++; } else { $relocateFile.PhysicalFileName = "$logFolder\$DatabaseName.ldf"; } $restore.RelocateFiles.Add($relocateFile) | out-null; } $restore.SqlRestore($server); } function CheckCredentials { If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) { Write-Warning “You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!” return $false } Write-Host "Done." return $true } function GrantPermissionToApplicationPool($iisApplicationPoolName, $containerDirectoryPath) { Write-Host "Grant RW directory level permission for" $iisApplicationPoolName "(" $containerDirectoryPath ")" $fullApplicationPoolName = "IIS AppPool\" + $iisApplicationPoolName GrantModifyPermissionToFolder $fullApplicationPoolName $containerDirectoryPath "Modify" Write-Host "Grant R directory level permission for IUSR" "(" $containerDirectoryPath ")" GrantModifyPermissionToFolder "IUSR" $containerDirectoryPath "Read" } function GrantModifyPermissionToFolder($userName, $path, $accessLevel) { $acl = Get-Acl $path $ar = New-Object System.Security.AccessControl.FileSystemAccessRule($userName, $accessLevel, "ContainerInherit,ObjectInherit", "None", "Allow") $acl.SetAccessRule($ar) Set-Acl $path $acl } function ScaffoldIIS($hostName, $hostIp, $iisApplicationPoolName, $iisApplicationPoolDotNetVersion, $iisApplicationName, $containerDirectoryPath) { SetHostsFile $hostName $hostIp RemoveDefaultWebSiteIfNeeded CreateOrUpdateApplicationPool $iisApplicationPoolName $iisApplicationPoolDotNetVersion CreateOrUpdateSite $iisApplicationName $iisApplicationPoolName $containerDirectoryPath $hostName GrantPermissionToApplicationPool $iisApplicationPoolName $containerDirectoryPath #foreach($application in $targetWebApplications) #{ # CreateOrUpdateApplication "$iisApplicationName\Kreta.Web.$application" (Join-Path $projectBasePath "$application\KretaWeb") #} Write-Host "IIS scaffolding has been successfully completed!" } function StartLogging { ScaffoldLoggingContainer try { Stop-Transcript } catch {} Start-Transcript -path $logFile -append } function StopLogging { try { Stop-Transcript } catch {} } function EnableEmbeddedIISFeatures { cd $PSScriptRoot $featureList = @("IIS-WebServerRole", "IIS-WebServer", "IIS-CommonHttpFeatures", "IIS-HttpErrors", "IIS-HttpRedirect", "IIS-ApplicationDevelopment", "IIS-NetFxExtensibility", "IIS-NetFxExtensibility45", "IIS-HealthAndDiagnostics", "IIS-HttpLogging", "IIS-LoggingLibraries", "IIS-RequestMonitor", "IIS-HttpTracing", "IIS-Security", "IIS-URLAuthorization", "IIS-RequestFiltering", "IIS-IPSecurity", "IIS-Performance", "IIS-HttpCompressionDynamic", "IIS-WebServerManagementTools", "IIS-ManagementScriptingTools", "IIS-IIS6ManagementCompatibility", "IIS-Metabase", "IIS-CertProvider", "IIS-WindowsAuthentication", "IIS-DigestAuthentication", "IIS-ClientCertificateMappingAuthentication", "IIS-IISCertificateMappingAuthentication", "IIS-StaticContent", "IIS-DefaultDocument", "IIS-DirectoryBrowsing", "IIS-WebSockets", "IIS-ApplicationInit", "IIS-ASPNET", "IIS-ASPNET45", "IIS-ASP", "IIS-CGI", "IIS-ISAPIExtensions", "IIS-ISAPIFilter", "IIS-ServerSideIncludes", "IIS-CustomLogging", "IIS-BasicAuthentication", "IIS-HttpCompressionStatic", "IIS-ManagementConsole", "IIS-ManagementService") Enable-WindowsOptionalFeature -FeatureName $featureList -Online > $null Write-Host "Done." } function ResetEnvironment { cd $PSScriptRoot Write-Host "Done." } function ResetIIS { & {iisreset} > $null Write-Host "Done." } function AddSslBindingToIdpAndAddAsTrustedCert($siteName, $dnsName) { $newCert = New-SelfSignedCertificate -DnsName $dnsName -CertStoreLocation cert:\LocalMachine\My New-WebBinding -Name $siteName -HostHeader $dnsName -Port 443 -Protocol https $binding = Get-WebBinding -Name $siteName -Protocol "https" $binding.AddSslCertificate($newCert.GetCertHashString(), "my") $tempCert = Join-Path "c:\Temp" $dnsName Export-Certificate -Cert $newCert -FilePath $tempCert -Type SST Import-Certificate -CertStoreLocation cert:\CurrentUser\Root -FilePath $tempCert Remove-Item $tempCert Write-Host "Done." } #endregion #region Private methods function SetHostsFile($hostName, $ip) { $hostsPath = "$env:windir\System32\drivers\etc\hosts" $measure = Get-Content $hostsPath | Select-String $hostName | measure | select -Property Count if($measure.Count -eq 0) { "`r`n" + $ip + "`t" + $hostName | Out-File -encoding ASCII -append $hostsPath Write-Host $hostsPath "Host file has been successfully updated!" } } function CreateOrUpdateApplicationPool($iisAppPoolName, $iisAppPoolDotNetVersion) { #navigate to the app pools root cd IIS:\AppPools\ #check if the app pool exists if (!(Test-Path $iisAppPoolName -pathType container)) { #create the app pool $appPool = New-Item $iisAppPoolName $appPool | Set-ItemProperty -Name "managedRuntimeVersion" -Value $iisAppPoolDotNetVersion Write-Host "$iisAppPoolName (application pool) has been successfully created!" } } function RemoveDefaultWebSiteIfNeeded { cd IIS:\Sites\ if (!(Test-Path "DefaultWebSite" -pathType container)) { return } Remove-Item IIS:\Sites\DefaultWebSite -Recurse Write-Host "DefaultWebSite has been successfully deleted!" } function CreateOrUpdateSite($iisAppName, $iisAppPoolName, $directoryPath, $listenerHost) { #navigate to the sites root cd IIS:\Sites\ #check if the site exists if (Test-Path $iisAppName -pathType container) { $targetApplication = "IIS:\Sites\$iisAppName" $previousSite = Get-Item $targetApplication $previousSiteLocation = $previousSite.physicalPath Remove-Item $targetApplication -Recurse -Force > $null Write-Host "Previous $iisAppName (site) has been successfully deleted! Physical location: $previousSiteLocation" } #create the site $iisApp = New-Item $iisAppName -bindings @{protocol="http";bindingInformation=":80:" + $listenerHost} -physicalPath $directoryPath $iisApp | Set-ItemProperty -Name "applicationPool" -Value $iisAppPoolName $newSite = Get-Item "IIS:\Sites\$iisAppName" $newSiteLocation = $newSite.physicalPath Write-Host "$iisAppName (site) has been successfully created! Physical location: $newSiteLocation" } function CreateOrUpdateApplication($applicationLocation, $directoryPath) { $location = "IIS:\Sites\$applicationLocation" $measure = Get-Item $location -ErrorAction Ignore | measure | Select -Property Count if($measure.Count -eq 0) { New-Item $location -Type Application -PhysicalPath $directoryPath > $null Write-Host "$location (application) has been successfully created!" } } function ScaffoldLoggingContainer { if(!(Test-Path $loggingDirectory)) { New-Item $loggingDirectory -ItemType Directory > $null } if((Test-Path $logFile)) { Remove-Item $logFile -Force > $null } New-Item $logFile -ItemType File > $null } function CheckLocalDbAvailable { $commandAvailable = Get-Command sqllocaldb -ErrorAction Ignore if([string]::IsNullOrWhiteSpace($commandAvailable)) { return $false } return $true } function CheckDbInstance($databaseName) { $result = SqlLocalDB.exe info | select-string -pattern $databaseName | measure if($result.Count -eq 2) { return $true } return $false } function CheckAndInstallLocalDb($databaseName) { if(!(CheckLocalDbAvailable)) { Write-Error "LocalDb is not available on your Computer!" exit 1 } if(!(CheckDbInstance $databaseName)) { Write-Host "Creating LocalDb..." $databaseName SqlLocalDB.exe create $databaseName SqlLocalDB.exe share $databaseName $databaseName Write-Host "Starting LocalDb..." $databaseName SqlLocalDB.exe start $databaseName Write-Host "Grant access to IIS APPPOOL\Kreta.IdentityProvider for LocalDb..." $databaseName GrantIdpAppPoolForLocalDb $databaseName } else { Write-Host $databaseName " is already exist!" } } function GrantIdpAppPoolForLocalDb($databaseName) { $server = "(localdb)\.\" + $databaseName sqlcmd -S $server -i GrantIdpForLocalDb.sql } #endregion #region Exports export-modulemember -function CheckAndInstallLocalDb export-modulemember -function CheckCredentials export-modulemember -function ResetIIS export-modulemember -function ResetEnvironment export-modulemember -function StartLogging export-modulemember -function StopLogging export-modulemember -function ScaffoldIIS export-modulemember -function EnableEmbeddedIISFeatures export-modulemember -function Backup-Database export-modulemember -function Drop-Database export-modulemember -function Restore-Database export-modulemember -function AddSslBindingToIdpAndAddAsTrustedCert #endregion