Skip to content

Instantly share code, notes, and snippets.

@klmallory
Last active November 22, 2017 16:24
Show Gist options
  • Save klmallory/0e9c0f4d4799de6f377235ab6dff9a09 to your computer and use it in GitHub Desktop.
Save klmallory/0e9c0f4d4799de6f377235ab6dff9a09 to your computer and use it in GitHub Desktop.
Powershell Configure Script
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<appSettings>
<add key="SigningCredential" value="X509SigningCredentials" />
<add key="webPages:Enabled" value="true" />
<add key="LocalServiceName" value="My Service" />
<add key="LocalServiceUri" value="{{appUri}}" />
</appSettings>
<system.web>
<membership defaultProvider="SQLMembershipProvider">
<providers>
<add name="SQLMembershipProvider" applicationName="MyService" type="System.Web.Security.SqlMembershipProvider" connectionStringName="AspNetConnection" maxInvalidPasswordAttempts="{{maxPasswordAttempts}}" minRequiredPasswordLength="{{minPasswordLength}}" minRequiredNonalphanumericCharacters="{{minSpecialChars}}" passwordStrengthRegularExpression="{{passwordRegEx}}" />
</providers>
</membership>
<profile defaultProvider="SQLProfileProvider" inherits="MembershipComponent.UserProfile, MembershipComponent" enabled="true">
<providers>
<clear />
<add name="SQLProfileProvider" applicationName="MyService" type="System.Web.Profile.SqlProfileProvider, System.Web" connectionStringName="AspNetConnection" />
</providers>
</profile>
<roleManager enabled="true" defaultProvider="SQLRoleService">
<providers>
<add name="SQLRoleService" connectionStringName="AspNetConnection" applicationName="MyService" type="System.Web.Security.SqlRoleProvider, System.Web" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="AspNetConnection" connectionString="Data Source = {{aspnetDataSource}};Integrated Security={{aspnetIntSecurity}};Initial Catalog={{aspnetInitialCatalog}};Application Name=App;{{aspnetUserId}}{{aspnetPwd}}" />
<add name="Entities" connectionString="metadata=res://*/EntityDataModel.AppDataModel.csdl|res://*/EntityDataModel.AppDataModel.ssdl|res://*/EntityDataModel.AppDataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source={{appDataSource}};initial catalog={{appInitialCatalog}};integrated security={{appIntSecurity}};MultipleActiveResultSets=True;App=EntityFramework;{{appUserId}}{{appPwd}}&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
param (
[Parameter(Mandatory=$true)][string]$envFile,
[string]$baseDir = "",
[string]$encrypt = "false",
[string]$resetServices = "false"
);
[bool]$encryptFile = $false;
if ($encrypt -eq "true"){
$encryptFile = $true; }
else {
$encryptFile = $false; }
[bool]$reset = $false;
if ($resetServices -eq "true"){
$reset = $true; }
else {
$reset = $false; }
#default executable config names
$appConfigName = "app.config.template";
#default executable config names
$appOutputName = "My.Service.exe.config";
#default executable config names
$appServiceName = "My Service";
write-host -fore yellow "Loading file $($envFile)";
# Load environment file.
$file = Get-Content $envFile
$envData=@{}
foreach ($row in $file) {
# skip commented lines.
if ($row.StartsWith("#")){continue}
#csv magic
$fields = $row.Split('|');
if (($fields -eq $null) -or ($fields.Count -eq 0)) {continue}
write-host -fore gray "Loading row $($fields[0]), $($fields[1])";
$envData.Add($fields[0], $fields[1]);
}
#Optional overrides for config names, allows us to run this against any folder
if($envData.ContainsKey("appConfigName")) {
$appConfigName = $envData["appConfigName"]; }
#Optional overrides for output names, allows us to output the config into any folder
if($envData.ContainsKey("appOutputName")) {
$appOutputName = $envData["appOutputName"]; }
[System.Collections.ArrayList]$configs = @();
[System.Collections.ArrayList]$outputs = @();
[string]$osDrive = "C:";
[string]$netVersion = "v4.0.30319";
if($envData.ContainsKey("osDrive")) {
$osDrive = $envData["osDrive"]; }
if ($envData.ContainsKey("appDir")) {
$appDir = $baseDir + $envData["appDir"] + "\$appConfigName";
$appOutDir = $baseDir + $envData["appDir"] + "\$appOutputName";
[void] $configs.Add($appDir);
[void] $outputs.Add($appOutDir);
if ($reset) {
write-host -fore magenta "Stopping service $($appServiceName)";
stop-service $appServiceName -PassThru -ErrorAction Continue; }
}
$count = 0;
foreach ($config in $configs) {
if (-not (Test-Path $config)) { write-host -fore red "File Not Found! $($config)"; $count += 1; continue; }
else{ write-host -fore yellow "Loading config $($config)"; }
$doc = (Get-Content $config -ReadCount 0)
foreach ($envField in $envData.GetEnumerator())
{
$k = "{{$($envField.Name)}}";
$v = $envField.Value;
write-host -fore gray "Replacing key '$($k)' with value '$($v)'";
#swap out each tag, couldn't be simpler
$doc = $doc -replace [regex]::escape($k), $v
}
#empty any remaining tags
$envDoc = $envDoc -replace '{{[\w]*}}', $v
write-host -fore yellow "Saving output to $($outputs[$count])";
$doc|Out-File $outputs[$count] -Encoding utf8;
$count += 1;
}
$count = 0;
foreach ($config in $configs) {
#create env.js file for client side routing.
if (-not (Test-Path $config)) { $count += 1; continue; }
$envIn = (Get-Item $config).DirectoryName + "\env.js.template";
if (-not (Test-Path $envIn)) { write-host -fore DarkYellow "env.js file not found $($envIn)"; $count += 1; continue; }
write-host -fore yellow "Opening $($envJs)";
$envDoc = (Get-Content $envIn -ReadCount 0)
foreach ($envField in $envData.GetEnumerator())
{
$k = "{{$($envField.Name)}}";
$v = $envField.Value;
write-host -fore gray "Replacing key '$($k)' with value '$($v)'";
#swap out each tag, couldn't be simpler
$envDoc = $envDoc -replace [regex]::escape($k), $v
}
#empty any remaining tags
$envDoc = $envDoc -replace '{{[\w]*}}', $v
if (-not (Test-Path $outputs[$count])) { write-host -fore DarkYellow "output file not found $($outputs[$count])"; $count += 1; continue; }
$envOut = (Get-Item $outputs[$count]).DirectoryName + "\env.js";
write-host -fore yellow "Saving $($envOut)";
$envDoc|Out-File $envOut;
}
if ($encryptFile)
{
#The System.Configuration assembly must be loaded
$configurationAssembly = "System.Configuration, Version=4.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
[void] [Reflection.Assembly]::Load($configurationAssembly)
foreach ($output in $outputs) {
#The executable file must be in the same path to encrypt the configuration file.
$absolutePath = (Get-Item $output).FullName -replace ".config", "";
if (-not (Test-Path $absolutePath)) { write-host -fore red "Executable Path Not Found! $($absolutePath)"; continue; }
$configuration = [System.Configuration.ConfigurationManager]::OpenExeConfiguration($absolutePath)
$section = $configuration.GetSection("connectionStrings")
write-host -fore gray "Encrypting file $($absolutePath), section $($section)";
if (-not $section.SectionInformation.IsProtected)
{
$section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
$section.SectionInformation.ForceSave = [System.Boolean]::True;
$configuration.Save([System.Configuration.ConfigurationSaveMode]::Modified);
}
write-host -fore green "Encryption succeded.";
}
}
#restart all services if we included the directory in the data file.
if ($reset) {
if ($envData.ContainsKey("appDir")) {
write-host -fore darkgreen "Starting service $($appServiceName)...";
start-service $appServiceName -PassThru; }
}
osDrive|C:
netVersion|v4.0.30319
appDir|\MySelfHostedApp\
appConfigName|app.config.template
appOutputName|App.config
appUri|http://localhost:1234
#Membership Provider
maxPasswordAttempts|5
minPasswordLength|6
minSpecialChars|0
passwordRegEx|^([0-9a-zA-Z\.!@#\$%\^\(\)\-_\']{6,20})$
#Database
appDataSource|.\SQLEXPRESS
appIntSecurity|SSPI
appInitialCatalog|MyDb
appUserId|
appPwd|
#ASPNET Database
aspnetDataSource|.\SQLEXPRESS
aspnetIntSecurity|SSPI
aspnetInitialCatalog|aspnetdb
aspnetUserId|user id=;
aspnetPwd|password=;
@klmallory
Copy link
Author

This is an example of a simple configure script intended to be used both in a development environment and for production.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment