• Home
  • Topics
    • Office 365
    • Teams
    • SharePoint
    • Exchange 2019
    • Exchange 2016
    • Exchange 2013
    • Hybrid
    • Certificates
    • PowerShell
    • Migration
    • Security
    • Azure
  • Blog
  • Podcast
  • Webinars
  • Books
  • About
  • Subscribe
    • Facebook
    • Twitter
    • RSS
    • YouTube

Practical 365

You are here: Home / Exchange Server / Using an XML Settings File for PowerShell Scripts

Using an XML Settings File for PowerShell Scripts

May 15, 2014 by Paul Cunningham 15 Comments

One of the most common feedback items for PowerShell scripts that I’ve published, such as Test-ExchangeServerHealth.ps1, is that having to edit the script to insert the correct email settings is a pain. The other is that the scripts are unsigned, requiring the execution policy of the machine running the script to be relaxed.

These two things go hand in hand. I don’t sign the scripts because they always need editing to work in your environment. And I include the settings that need editing in the script, instead of making them parameters, because I want the script to be easy to run (a lot of parameters seems to increase the number of “How do I…?” questions I get).

To solve these issues, at least partially (people may still choose to edit scripts to customize their operations in other ways), I am looking at breaking these settings out into a separate file instead.

Here is a demonstration of how this would work. I’ve created a simple demo script and Settings.xml file to go with it.

powershell-xml-settings-01

The PowerShell script is quite simple – it sends an email message.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<# .SYNOPSIS Script Settings File Demo #>
 
[CmdletBinding()]
param ()
 
#-------------------------------------------------
#  Variables
#-------------------------------------------------
 
$myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
 
# Import email settings from config file
[xml]$ConfigFile = Get-Content "$MyDirSettings.xml"
 
$smtpsettings = @{
    To = $ConfigFile.Settings.EmailSettings.MailTo
    From = $ConfigFile.Settings.EmailSettings.MailFrom
    Subject = "Email Subject Line Goes here"
    SmtpServer = $ConfigFile.Settings.EmailSettings.SMTPServer
    }
 
$body = "Email body goes here"
 
#-------------------------------------------------
#  Script
#-------------------------------------------------
 
try
{
Send-MailMessage @smtpsettings -Body $body -ErrorAction STOP
}
catch
{
    Write-Warning $_.Exception.Message
}
 
#-------------------------------------------------
#  The End
#-------------------------------------------------

The script imports the Settings.xml file to determine the various email settings it should use.

1
2
# Import email settings from config file
[xml]$ConfigFile = Get-Content "$MyDirSettings.xml"

The XML file itself is also quite simple.

powershell-xml-settings-02

The script uses the data in the XML file to set parameters for the email message. Values can still be set directly in the script (like the email subject below), but I think it will make more sense to put them in the XML file instead.

1
2
3
4
5
6
$smtpsettings = @{
    To = $ConfigFile.Settings.EmailSettings.MailTo
    From = $ConfigFile.Settings.EmailSettings.MailFrom
    Subject = "Email Subject Line Goes here"
    SmtpServer = $ConfigFile.Settings.EmailSettings.SMTPServer
    }

When the script is executed an email message is sent. Simple as that.

This concept extents beyond just the email settings for scripts. Several of my scripts also include other variables such as alert thresholds, text strings for different languages, and so on. The more of these that are moved into a Settings.xml file like the above demonstration uses, the fewer reasons there will be to edit a script file directly.

If you have any feedback or comments on this I’d love to hear them.

Exchange Server PowerShell, Scripts

Comments

  1. Adam says

    February 21, 2019 at 10:58 pm

    Hi Paul

    Thanks for sharing

    Can you please advise if there is a way to define the settings file outside the script so i can reuse the script with multiple settings files e.g:

    powershell.exe c:\scripts\myscript.ps1 -switchforsettings c:\script\settings1.xml
    powershell.exe c:\scripts\myscript.ps1 -switchforsettings c:\script\settings2.xml
    powershell.exe c:\scripts\myscript.ps1 -switchforsettings c:\script\settings3.xml

    I know I could create separate folders for each instance which contains the script and settings file for each program (and the script would be identical) but then I would have multiple copies of the code to maintain.

    Any ideas would be very well received

    Many thanks
    Adam

    Reply
  2. himanshuk says

    June 5, 2018 at 2:18 pm

    Paul, for all scripts in one bunch of module how to prepare single json or psxml files and write all the cmdletbindings defined all parameters in it so that from the single psxml file we can call all the parameters anywere in individual scripts in module

    Reply
  3. Wil C says

    April 12, 2018 at 5:19 am

    Anythoughts on best way to encrypt strings in the XML config? I am using something similar to above, but have a password paramater in config id like secure.

    Reply
    • Paul Cunningham says

      April 12, 2018 at 11:49 am

      If you take a look at my stored creds functions here…

      https://github.com/cunninghamp/PowerShell-Stored-Credentials/blob/master/Functions-PSStoredCredentials.ps1

      …you’ll see how passwords can be securely stored in plain text files (which includes XML).

      Reply
  4. Gonz says

    March 24, 2018 at 2:17 am

    Nices, stills works even on a macOS with Powershell Core

    Reply
  5. Michael says

    January 17, 2018 at 6:09 am

    Brilliantly clear post and EXACTLY what I was looking for!

    Reply
  6. Van Fanel says

    May 19, 2016 at 4:30 am

    Wonderful post! Thanks Paul!

    Reply
  7. Wouter says

    October 8, 2015 at 5:36 pm

    How to access the path of the script? I want to be able to just put the script and it’s config anywhere and let the script read the config file from the same folder. Regardless of where the script is called from.

    Reply
    • James L says

      January 7, 2016 at 9:22 pm

      Use $PSScriptRootsettings.xml

      This will prefix the the settings.xml path to the same as the script that executed it.

      Reply
  8. Richard A says

    June 11, 2015 at 8:52 pm

    @Paul Cunningham – On the previous version of Get-DailyBackupAlerts it was posssible to have multiple recipients in the To field. This was achieved by seperating each in inverted commas, with a comma between (e.g. From = “1@xyz.com”,”2@abc.com”,”3@aaa.com). This no longer seems possible with the Settings.xml file. Please would you advise me how to do this?

    Reply
    • Paul Cunningham says

      June 11, 2015 at 10:55 pm

      I recommend using a distribution group.

      Reply
      • Mike says

        August 4, 2015 at 8:08 pm

        @Richard and Paul

        A bit late but I had the same problem as you Richard.

        When setting the $smtpsettings hashtable, I changed the ‘To’ key to be:

        To= @($ConfigFile.Settings.EmailSettings.MailTo.Split(“,”).Trim())

        The XML line is:

        MailTo>user1@domain.com,user2@domain1.com etc.

        This seems to have done the trick.

        Mike

        Reply
  9. Richard Voogt says

    August 20, 2014 at 5:07 am

    Nice way to use the script in many different enviroments, like i do.
    Thanks for the hint, i’m going to use this in my scripts.

    Reply
  10. Me says

    May 16, 2014 at 11:38 am

    No complains here:)
    I don’t think its a lot of work to edit a script somebody talented like you wrote.
    Thanks for the effort you put into it

    Reply
  11. Michel de Rooij says

    May 15, 2014 at 10:52 pm

    Depends on the purpose. To maximize flexibility and general purpose usage, I parametrize stuff. Yes, that will increase erroneous usage but I see that as part of the learning curve of the one running the script. For testing or repeated usage, I use splatting for all or specific parameters like you do yourself (‘@’), you only read them from an XML in your script. Downside is that this creates a dependency (on that file) and requires proper syntax and XML (where some characters aren’t allowed). On the plus side, they can send you that XML to try to reproduce issues etc. or you can use it to run scheduled jobs (without zillions of parameters). I use an XML file for my Install-Exchange2013 script to save parameters and state information in between reboots.

    Reply

Leave a Reply Cancel reply

You have to agree to the comment policy.

Recent Articles

  • The Practical 365 Weekly Update: S2, Ep 9 – Controversial Teams guest changes and a roundup of important Microsoft 365 announcements and features
  • Hands-on SharePoint Syntex Blog Series – Part I
  • The Practical 365 Weekly Update: S2, Ep 8 – What to expect in 2021, Solarigate, TLS in Exchange and new Teams updates
  • Security updates released for Exchange and SharePoint Servers 2010 to 2019
  • The Practical 365 Weekly Update: S2, Ep 7 – Urgent Exchange security updates, new Teams features launch
Practical 365

Related Posts

Related Posts

Training Courses

  • Configuring and Managing Office 365 Security
  • Office 365 Admin Playbook
  • Exchange 2016 Exam 70-345
  • Managing Exchange Mailboxes and Distribution Groups in PowerShell
  • More Training Courses...

Recommended Resources

  • Office 365 Security Resources
  • Office 365 Books
  • Exchange Server Books
  • Exchange Server Migrations
  • Exchange Analyzer
  • Digicert SSL Certificates

About This Site

Practical 365 is a leading site for Office 365 and Exchange Server news, tips and tutorials. Read more...

Find out more about advertising with us.

Contact us


Subscribe to our newsletter
  • Facebook
  • Twitter
  • RSS
  • YouTube

Copyright © 2021 Quadrotech Solutions AG · Disclosure · Privacy Policy
Alpenstrasse 15, 6304 Zug, Switzerland