How do I read/write App.config settings with PowerShell? - powershell

I'd like to use PowerShell as part of our automated build process to update an App.config file while deploying into our test environment. How can I do this?

Given this sample App.config: C:\Sample\App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="dbConnectionString"
connectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=True"/>
</connectionStrings>
</configuration>
The following script, C:\Sample\Script.ps1, will read and write a setting:
# get the directory of this script file
$currentDirectory = [IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path)
# get the full path and file name of the App.config file in the same directory as this script
$appConfigFile = [IO.Path]::Combine($currentDirectory, 'App.config')
# initialize the xml object
$appConfig = New-Object XML
# load the config file as an xml object
$appConfig.Load($appConfigFile)
# iterate over the settings
foreach($connectionString in $appConfig.configuration.connectionStrings.add)
{
# write the name to the console
'name: ' + $connectionString.name
# write the connection string to the console
'connectionString: ' + $connectionString.connectionString
# change the connection string
$connectionString.connectionString = 'Data Source=(local);Initial Catalog=MyDB;Integrated Security=True'
}
# save the updated config file
$appConfig.Save($appConfigFile)
Execute the script:
PS C:\Sample> .\Script.ps1
Output:
name: dbConnectionString
connectionString: Data Source=(local);Initial Catalog=Northwind;Integrated Security=True
Updated C:\Sample\App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="dbConnectionString"
connectionString="Data Source=(local);Initial Catalog=MyDB;Integrated Security=True" />
</connectionStrings>
</configuration>

The code can be much more shorter (based on Robin's app.config):
$appConfig = [xml](cat D:\temp\App.config)
$appConfig.configuration.connectionStrings.add | foreach {
$_.connectionString = "your connection string"
}
$appConfig.Save("D:\temp\App.config")

Related

read nuget.config programmatically in c#

Is it possible to read nuget.config file and packages sources inside with using Nuget.visualStudio,nuget.core or nuget.clients dll.I can parse xml but is there any outofthebox logic in nuget.dlls
Yes! You need to consume the NuGet.Configuration package available at https://www.nuget.org/packages/NuGet.Configuration/4.6.2.
Then you can use the following code -
using NuGet.Configuration;
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
// basic implementation of nuget.config in code
var setting = Settings.LoadSpecificSettings(#"f:\root", "nuget.config");
// get sources
var packageSourceProvider = new PackageSourceProvider(setting);
var sources = packageSourceProvider.LoadPackageSources();
foreach(var source in sources)
{
Console.WriteLine($"{source.Name}: {source.SourceUri}");
}
}
}
}
This will generate the following output -
NuGet.org: https://api.nuget.org/v3/index.json
Sample config file used (lets say at path f:\root\nuget.config)-
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

web.config changes for KB3159706

i spent a few hours trying to code this by myself, but i don't know much about editing the web.config and all the examples i found don't come close to what i need. CHANGE#1 is unique because it does include the typical key=value.
I want to be able to script (PowerShell) the required modifications of Web.Config, only if the values do not already exist.
CHANGE#1:
Onsert this
(if not already there and "true"): multipleSiteBindingsEnabled="true"
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
CHANGE#2:
Insert this if not already there:
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="SSL"
contract="Microsoft.UpdateServices.Internal.IClientWebService" />
<endpoint address="secured"
binding="basicHttpBinding"
bindingConfiguration="SSL"
contract="Microsoft.UpdateServices.Internal.IClientWebService" />
It goes between here:
<services>
<service
name="Microsoft.UpdateServices.Internal.Client"
behaviorConfiguration="ClientWebServiceBehaviour">
<!-- ... CODE FROM CHANGE#2 GOES HERE ... -->
</service>
</services>
This is the code so far for change#1 (not working):
$sWSUSwebConfig = "C:\Program Files\Update Services\WebServices\ClientWebService\Web.Config"
$xFileContent = [Xml](Get-Content $sWSUSwebConfig)
$root = $xFileContent.get_DocumentElement()
foreach ($item in $root."system.serviceModel"."serviceHostingEnvironment") {
if ($item."multipleSiteBindingsEnabled" -ine "true") {
$activeConnection = $root.serviceHostingEnvironment
$activeConnection.SetAttribute("multipleSiteBindingsEnabled", "true")
#$item.add."multipleSiteBindingsEnabled" = "true"
$iKeyFound = $true
}
}
$xFileContent.Save("c:\temp\web.config")
Reference for modifications: step 3 from kb3159706.

ASP.NET Routing in rest service not working in IIS

I created a simple rest service with routing enabled. The routing is properly working when i run it locally i.e using asp.net development server. But when I deploy the application in IIS (IIS 7.5) then it and try to access the method in the service i get the error HTTP 404.0 Not found. Here is my code :
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class HelloWorldService
{
[WebGet(UriTemplate = "Date")]
public DateTime Date()
{
return System.DateTime.Now;
}
}
Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("ServiceData", new WebServiceHostFactory(), typeof(HelloWorldService)));
}
Web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
I also Enabled HTTP Redirection Feature under
Windows Features -> Internet Information Services -> Word Wide Web services -> Common HTTP Features
I also tried Adding handlers like
<handlers>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</handlers>
Also i have tried all the other solutions that were suggested on the web but nothing works. Thanks in advance for any help.
Something is wrong with your RegisterRoutes(). It should be:
private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("HelloWorldService", new WebServiceHostFactory(), typeof(HelloWorldService)));
}

SSRS 2008 Execution Service LoadReport Error

I'm using SSRS 2008 (NOT R2)
I have a report deployed to a dev server, I'm trying to render the report as a pdf by calling the execution service.
The error I am getting is
This operation is not supported on a report server that runs in native mode. ---> Microsoft.ReportingServices.Diagnostics.Utilities.OperationNotSupportedNativeModeException: This operation is not supported on a report server that runs in native mode.
Two things I notice: one is that web service wsdl shows LoadReport having two parameters - report path and history id, but when I generate a service reference for the ReportExecution2005.asmx, the LoadReport method has 5 parameters: trusteduserheader, reportPath, historyid, serviceinfoheader, and executionheader
I have tried adding the service reference with and without ?wsdl at the end of the url but the result is the same
Here's the code I'm using:
ReportExecutionServiceSoapClient rs = new ReportExecutionServiceSoapClient("ReportExecutionServiceSoap", "http://xxx:80/ReportServer/ReportExecution2005.asmx");
rs.ClientCredentials.Windows.ClientCredential = new NetworkCredential("aaa", "aaa", "aaa");
rs.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
// Render arguments
byte[] result = null;
string reportPath = "/Invoices/InvoiceStandard";
string format = "PDF";
string historyID = null;
string devInfo = "";
// Prepare report parameter.
ParameterValue[] parameters = new ParameterValue[3];
parameters[0] = new ParameterValue();
parameters[0].Name = "PartyID";
parameters[0].Value = "19758";
parameters[1] = new ParameterValue();
parameters[1].Name = "Contract";
parameters[1].Value = "17703"; // June
parameters[2] = new ParameterValue();
parameters[2].Name = "FinancialPeriod";
parameters[2].Value = "MAR-2012";
string encoding="";
string mimeType="";
string extension="";
Warning[] warnings = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
TrustedUserHeader trusteduserHeader = new TrustedUserHeader();
ExecutionHeader execHeader = new ExecutionHeader();
ServerInfoHeader serviceInfo = new ServerInfoHeader();
execHeader = rs.LoadReport(trusteduserHeader, reportPath, historyID, out serviceInfo, out execInfo);
rs.SetExecutionParameters(execHeader, trusteduserHeader, parameters, "en-us", out execInfo);
try
{
rs.Render(execHeader,
trusteduserHeader,
format,
devInfo,
out result,
out extension,
out encoding,
out mimeType,
out warnings,
out streamIDs);
}
Here's my web.config
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login.aspx" timeout="2880" />
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ReportExecutionServiceSoap" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://xxx:80/ReportServer/ReportExecution2005.asmx"
binding="basicHttpBinding" bindingConfiguration="ReportExecutionServiceSoap"
contract="SSRS.ReportExecutionServiceSoap" name="ReportExecutionServiceSoap" />
</client>
</system.serviceModel>
</configuration>
I had the same problem with SSRS 2008 R2, but I did not want to resort to calling the report viewer control.
Above, Rick Hodder was using the following statement:
TrustedUserHeader trusteduserHeader = new TrustedUserHeader();
This statement will cause the OperationNotSupportedNativeModeException error he encountered if the SSRS installation is not configured with a certificate for SSL connections. Check the SSRS Logs for an error entry that contains:
ERROR: TrustedHeader Not Supported in Native Mode.
If this is the case, you need to either configure the server to work with SSL, or use null for the trusted header.
TrustedUserHeader trusteduserHeader = null;
Is this report loaded from some front end or is it loaded from DLL? To me it looks like you are using ASP.net Application. In this case you could use reportViewer object to pull the report for you all the heavy lifting can be done by the ReportViewer and you can then just save the file as PDF
using something like this
reportViewer.ServerReport.ReportServerUrl = new Uri(Config.ReportServerURL);
reportViewer.ServerReport.ReportPath = String.Format("{0}/{1}", Config.ReportServerEnvironment, reportName);
reportViewer.ServerReport.ReportServerCredentials = new ReportsCredentials(Config.ReportServerUser, Config.ReportServerPassword, Config.ReportServerDomain);
reportViewer.GetDocumentStream(SSRSFormatType.Pdf, documentName);
Here reportViewer is the reference to ReportViewer object on the screen.

C# Interactive and Entity Framework

I am trying to run a method in C# Interactive that return some data from local db using Entity Framework. But it return an error saying that the connection string named 'InteractiveConsoleDBEntities' could be found in the application config file.
I am using data base first.
I use the option "Initialize Interactive with project" to start with C# Interactive.
Here is the details...
Commands in Interactive Console
#r "C:\Users\Path\InteractiveConsole\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.ComponentModel.DataAnnotations.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Core.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.Entity.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Runtime.Serialization.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Security.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.Linq.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.DataSetExtensions.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Microsoft.CSharp.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.dll"
#r "InteractiveConsole.exe"
using InteractiveConsole;
using InteractiveConsole.Model;
using InteractiveConsole.DAL;
var context = new InteractiveConsoleDBEntities();
context.Employees.ToList();
Then I get the error
No connection string named 'InteractiveConsoleDBEntities' could be found in the application config file.
+ System.Data.Entity.Internal.LazyInternalConnection.get_ConnectionHasModel()
+ System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
+ System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(System.Type)
+ InternalSet<TEntity>.Initialize()
+ InternalSet<TEntity>.Include(string)
+ DbQuery<TResult>.Include(string)
+ System.Data.Entity.DbExtensions.Include<T>(IQueryable<T>, string)
+ System.Data.Entity.DbExtensions.Include<T, TProperty>(IQueryable<T>, Expression<Func<T, TProperty>>)
+ InteractiveConsole.DAL.EmployeeDAL.GetEmployeeList()
The App.config file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v13.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
<connectionStrings>
<add name="InteractiveConsoleDBEntities" connectionString="metadata=res://*/Model.Model.csdl|res://*/Model.Model.ssdl|res://*/Model.Model.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\DB\InteractiveConsoleDB.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
The DbContext
namespace InteractiveConsole.Model
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class InteractiveConsoleDBEntities : DbContext
{
public InteractiveConsoleDBEntities()
: base("name=InteractiveConsoleDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Person> People { get; set; }
}
}
The class with method
using System.Data.Entity;
namespace InteractiveConsole.DAL
{
public class EmployeeDAL
{
public static List<Employee> GetEmployeeList()
{
using (var context = new InteractiveConsoleDBEntities())
{
return context.Employees.Include(x => x.Person).ToList();
}
}
}
}
The same project in Immediate Window works fine
InteractiveConsole.DAL.EmployeeDAL.GetEmployeeList()
Count = 2
[0]: {System.Data.Entity.DynamicProxies.Employee_0D99EB301BB74EDFF2203163D6E8A936C70F24995F1639BF58D81DCCA671DEC0}
[1]: {System.Data.Entity.DynamicProxies.Employee_0D99EB301BB74EDFF2203163D6E8A936C70F24995F1639BF58D81DCCA671DEC0}
Hope some one know what I doing wrong and can help me.
Thanks a lot
Struggled with this one for a while before I finally got it working.
Create a new partial class (for example named YourEntities.cs) with a new overload for your constructor that takes a connection string parameter (don't modify your existing class as it will be overwritten whenever you re-model the database):
using System.Data.Entity;
namespace YourNamespace.Models
{
public partial class YourEntities : DbContext
{
public YourEntities(string connectionString)
: base(connectionString)
{
}
}
}
Then, build your project, right click it and click "Initialize Interactive with Project". Open your web.config / app.config and copy the connection string to your clipboard.
In the interactive window, paste this replacing ConnStringHere with your connection string but don't hit enter:
var db = new YourNamespace.Models.YourEntities("ConnStringHere");
After you paste, replace " in the connection string with \" , go to the end of the line in C# interactive and hit enter.
Then you should be able to use db in your C# Interactive window it as if it were in your app:
Print(db.Employees.Count());
I realize this is old, but I found a way to make this work without changing my code, or creating any proxies or other work-around code. I was able to make this work by editing the config file for the interactive window, itself. See my answer in this post:
Project can't find my EF connection string in C# Interactive
You may have to add other config data, as well, if your app relies on it. Just adding the connection string was enough, for me.