Improving the User Experience in a ConfigMgr OS Upgrade Task Sequence

Update 24th Nov 2017

  • Fixed the issue where the Upgrade Successful notification does not display for non-admin users. Thanks to a tip from Carl (see comments) I used a somewhat ancient mechanism called ActiveSetup that is still available in Windows 10.
  • The custom background displayed during the online phase of the upgrade now displays on all screens if multiple monitors are being used. Thanks to Ronni Pedersen for the kick 🙂
  • These changes have added a couple more scripts to the download, but the task sequence remains unchanged, so simply update your notifications package in ConfigMgr.

When upgrading to Windows 10 from a ‘down-level’ OS, or to a new version of Windows 10, using installation media, you get a nice UI that guides you through the installation process.


Upgrading using an OS upgrade task sequence in ConfigMgr however, is a comparatively cold experience with no UI except for the TS Progress UI – assuming you enable that. For an IT admin of course, we don’t necessarily care about having a nice UI, we just care that it works and we have log files to check if it doesn’t. But for an end user that can be a different story. It may be a little disconcerting to some that their system is being upgraded yet the upgrade process is providing little feedback about what is happening. Once you get past the online phase of the upgrade however, the experience is more streamlined.

In an OS upgrade task sequence, Windows Setup will be running silently in SYSTEM context so it will not display anything to the logged-on user. Everything is handled by the task sequence. If the task sequence fails, the user might feel panicked and wonder if they have lost any of their data or applications. There is nothing to reassure them otherwise.

We may not be able to reproduce the nice Windows Installer UX, but we could at least add a few custom notifications at different points in the TS to provide some feedback to the end user and improve the overall experience from their perspective.

I experimented with this a bit using my New-WPFMessageBox PowerShell function and the following is what I came up with.

At the start of the upgrade task sequence, I like to check the currently-installed Windows version because – strange but true – the Windows Setup process will not prevent you from ‘upgrading’ to a version you are already running! How’s that for a time-waster?! Of course, you would try to avoid that with correct collection targeting in ConfigMgr, but just as an insurance I check that the system is not already running that version, and if it is, display the following notification to the user, then exit the TS.


Next, during the online phase of the Upgrade Operating System step, I display a custom background. This is just to discourage the user from working or rebooting the computer and provides some extra assurance that something is actually happening. This is actually a WPF window that fills the screen, not a desktop wallpaper.


I also run the compatibility scan first and if that fails, I notify the user with the error code and description that they can contact IT support with:


The same if the upgrade fails, or if a rollback is performed, although no descriptions here as there are many possible result codes.



Finally, when the OS upgrade successfully completes, the first user who logs in will see the following notification giving them some hyperlinks to what is new in the upgraded OS:


Using my New-WPFMessageBox function you can customise these notifications as you please.

To make it simple, I have included here an export of an OS upgrade task sequence that you can import into your environment as a basis or an example of how to add such notifications. Here’s a screenshot:


I’ve also made available all the PowerShell scripts I used as a download. Simply create a standard package in ConfigMgr containing the all the scripts in the same directory and distribute the content (no program required). Update the imported task sequence to reference this package for each of the Run PowerShell script steps, and also reference your OS Upgrade package in the relevant steps.

Some important things to note:

  • The notifications display in the context and session of the logged-on user. This is accomplished by calling the notification scripts via another script – Invoke-PSScriptAsUser.ps1 – that creates a PowerShell process in the user’s context.
  • Where a notification is displayed, I also first hide the TS Progress UI using the TSDisableProgressUI variable, which is available since ConfigMgr Current Branch 1706. This is because the notification will display behind the TS Progress UI, although if there are no further steps to complete after the notification is displayed it doesn’t matter too much because the TS Progress UI will not display for long anyway. The task sequence will not wait for the user to respond to the notification before it continues processing any remaining steps.
  • Where the compatibility scan or OS upgrade fails, the step is set to continue on error so that we can handle the error ourselves. After displaying the error notification, we manually fail the TS using the _SMSTSOSUpgradeActionReturnCode TS variable value as the error code.
  • Where the compatibility scan or OS upgrade fails, we write out the return code to a file so that the custom notification, which runs in the user context, can read in the value. This is because the task sequence variables are only available to query in the SYSTEM context – the user context cannot read them.
  • In handling a failure I set the SMSTSErrorDialogTimeout TS variable to 1 second so that the TS fails quickly and the user is left with our custom error notification instead of the default TS one.
  • The final notification that the upgrade was successful displays for the first user that logs in after the TS has completed. This is because the OS Upgrade TS simply ends at the Windows lock screen where we cannot display anything. Before the TS ends, we copy the notification script to a temp location and set the RunOnce registry key to call it.
  • Pay attention to the step conditions for the groups in the task sequence, as this controls the logical flow of the sequence.
  • Make sure to “Ignore dependency” when importing the task sequence

Pre-caching Content

Another important activity that should be done before making an OS Upgrade task sequence available is to pre-cache as much content as possible on the target systems. Unless the content is already in the ConfigMgr client cache when the TS runs, it’s gonna need to download that content which, for an OS Upgrade TS, is a sizeable amount of data and could add significant time to the execution of the task sequence making for a poorer experience for the end user.

Since ConfigMgr 1702, we have had the ability to pre-download content for a task sequence, and this was improved a bit in 1706, but in my own experience I have not found it to do quite what it says on the tin. Specifically, this line in the documentation – When the client receives the deployment policy, it will start to pre-cache the content. – appears not to be true (at the time of writing with 1706). Even when you have correctly set the OS Architecture and language on the OS Upgrade package, and set the required conditions on the Upgrade Operating System step, no content is actually cached on the client until the date the deployment becomes available. That is, you can target a system with a deployment that has an available date in the future, and theoretically it should start caching content as soon as a machine policy refresh occurs. But in practice, it does not cache any content until the available date of the deployment is reached, then shortly after it will start to download the content. If the user decides to upgrade as soon as the deployment becomes available, they will need to wait for the content to download first. If anyone has a different experience with this, please let me know!

Until that is fixed, we can still pre-cache most of the content by creating a hidden task sequence that uses the Download Package Content step. Make sure to use the Configuration Manager client cache as the location.


Check the option to Suppress task sequence notifications on the TS properties, and deploy the TS to the target systems before you deploy the OS Upgrade TS.



Download the PowerShell Scripts and exported Task Sequence here.

81 thoughts on “Improving the User Experience in a ConfigMgr OS Upgrade Task Sequence

  1. Hi Trevor,
    Nice work! do you now if it is possible to pass the button click to a TS variable so we can make the user postpone the update ?

    1. Hi Bend, yes it’s possible but you would need to write the button click output to file and then run another script to read it, because the notifications run in the user context where you can’t read or write TS variables.

      As an example, if you add a button called “POSTPONE” to the notification, you could run this code in your notification script to write the output to file:
      New-WPFMessageBox @Params
      If ($WPFMessageBoxOutput -eq “POSTPONE”)
      # Set variables
      $SaveToRoot = “$env:SystemDrive”
      $SaveToDirectory = “temp”
      $SaveToLocation = “$SaveToRoot\$SaveToDirectory\”
      $FileName = “POSTPONEUPGRADE.txt”

      # Create the temp directory if doesn’t exist
      If (!(Test-Path $SaveToLocation))
      $null = New-Item -Path $SaveToRoot\ -Name $SaveToDirectory -ItemType “directory” -Force

      “TRUE” | Out-File -FilePath “$SaveToLocation\$FileName” -Force
      Then run the following script in another TS step to read the file and write to a TS variable:
      # Read the POSTPONEUPGRADE.txt file
      $ReadFromRoot = “$env:SystemDrive”
      $ReadFromDirectory = “temp”
      $ReadFromLocation = “$ReadFromRoot\$ReadFromDirectory\”
      $FileName = “POSTPONEUPGRADE.txt”
      $PostponeUpgrade = Get-Content “$ReadFromLocation\$FileName” -ErrorAction SilentlyContinue

      If ($PostponeUpgrade -eq “TRUE”)
      # Set the TS variable
      $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
      $tsenv.Value(“PostponeUpgrade”) = “true”

      # Cleanup file
      Remove-Item “$ReadFromLocation\$FileName” -Force
      # Set the TS variable
      $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
      $tsenv.Value(“PostponeUpgrade”) = “false”

      1. Thanks for quick response.. could be awesome if it was possible to display a counter, with a delay so the user eventually was forced to do the upgrade, like with Powershell app deploy toolkit.. do you know if that is possible in user context ? Or I could just use Powershell app deploy to create the file, and then kick off your script..

        Could be nice to keep it all in your script though 🙂

      2. That is possible but would require some custom WPF added to the notification. You would also need a mechanism to wait for a response as the TS will not wait by default.
        But I’m intrigued why you would want to postpone a running TS. Why not just make it available with a deadline?

      3. Because users forget, and if the deadline is passed, it will be forced and interrupt their work.. I work at a law firm, those are not easy users 🙂 they would just keep postponing it with the first solution I guess..

  2. Hello, great work. I’ve tested this out and all works well except for the final notification that the upgrade is complete when the user logs on. For some reason the runonce doesnt trigger for the user when logging in after the upgrade. Any ideas?

      1. Hi Trevor, the file is in c:\temp and runone key set, but just doesnt run at the next logon. Running the command manually works fine.

      2. Hi, looking into the RunOnce keys only work if the user logging on is an administrator (this works). However this wont be the case normally so need to find alternative method.

  3. To work around this, I’ve used an ActiveSetup to run the PowerShell script and as the last step in the script, deleted the script from c:\temp so that this only runs for the first user who logs onto the machine. This appears to work well.

      1. Trevor did you you make the changes you implemented in your example, if not can you provide some detail on how you made it work.

  4. Hi, I have a couple questions about this. Is the custom background supposed to survive a reboot or do we need to run it after every reboot during the upgrade process? Another question: is there a way we can bring up a command prompt without making the custom background go away? Kind of like the ability to press F8 in WinPE. Also, it would be nice if it showed during the lock screen too so the user doesn’t try to login. Thanks for all the work you’ve been doing on this.

    1. Hi Chris, the custom background only displays (and is only needed) during the online (down-level) phase of the upgrade. After the first restart, windows setup enters WinPE where the user experience is streamlined with upgrade methods. The custom background only masks the desktop which is still running, so you can still do ctrl-alt-del for example to bring up task manager and start a process, or Alt-Tab to switch applications.

      1. Right, I understand that, but our task sequence has custom reboots both before and after the upgrade. First we run the readiness and assessment, then update the BIOS and reboot, then OS upgrade happens. After the upgrade there is some hardware changes that might cause a reboot and then there a few steps that happen after that, and an install updates step.

      2. That would be difficult to achieve unless you reboot into WinPE and do your extra activities there, or configure an auto logon then display the custom background again. But even then the ConfigMgr client takes an minute or two before it’s ready and the TS continues. There’s not a lot you can do at the Windows ctrl-alt-delete / lock screen to my knowledge.

  5. Thanks for this! I am having an issue though where if I run the pre-cache task sequence, I can see the files in the cache. Once i run the actual upgrade I can see it still downloading file to the working directory, so I have 2 copies of the content on the machine. Any ideas?

      1. Ah, that will do it. Unfortunately I was trying to avoid that because we want to have a single task sequence for multiple models…and we download drivers specific to each model…I’ll keep looking, thanks!

  6. I have integrated this and when a win10 upgrade fails during the “upgrade the Operating System” step the custom background never goes away, so the user is unable to see the error message unless you right click the custom background.

    Any ideas?

    1. That should not be the case if you set the Upgrade Operating System to continue on error as per the example task sequence. The system should reboot and then the task sequence will handle the error with the custom steps.

      1. The upgrade OS step failed before a reboot was initiated (0x80004005), so the reboot never occurred and the custom background window stayed in the foreground. The TS Notification was hidden and the error message was shown, but only after I right clicked the purple screen could a user see the error message.

      2. Sounds like your TS is not configured as per the example? Question is: if the Upgrade OS step is set to continue on error, why did it not continue? Only if it continues can we handle the error with a custom notification.

  7. Thanks, I double checked your example and see I missed a restart computer step after the upgrade and before the OS Upgrade Failed step. Added that back and will see how it goes!

  8. Great stuff Trevor! Is there a way to email me when the TS initiated and failed with the subject contains computer name and model ?

    1. Certainly that’s possible, you can simply add a PS script that uses Send-MailMessage or the .Net mail classes. But when sending email from a client you need to check whether your smtp server permits a relay and whether authentication is required and which address you can send from.
      If you have Orchestrator you can also use that to send email, which is something I do for our OSD task sequences.

  9. Thanks Trevor for the quick reply! Does this work from windows 7 to 10? I got this error when the custom background ran

    ” Add-Type : (0) : Metadata file ‘System.Runtime.InteropServices.dll’ could not b RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    e found RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    (1) : using System; RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    At C:\_SMSTaskSequence\Packages\PR10056E\Invoke-PSScriptAsUser.ps1:283 char:9 RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    + Add-Type <<<< -ReferencedAssemblies 'System', 'System.Runtime.InteropService RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    s' -TypeDefinition $Source -Language CSharp -ErrorAction Stop RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    + CategoryInfo : InvalidData: (error CS0006: M…ld not be found: RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    CompilerError) [Add-Type], Exception RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands. RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)
    AddTypeCommand RunPowerShellScript 12/20/2017 4:11:42 PM 2980 (0x0BA4)"

  10. I’d like to add, I want to keep the ability to “Upgrade” on the OS version level. Imagine a scenario where say, an app was stripped out that the customer actually needed. Or maybe someone upgraded on their own by manually scanning for updates on a network that was not preventing them from doing so. Running a 1709 to 1709 upgrade is a great way to save all the user data and get the user back to a standard build. Aside from this little note, I’d like to thank you for posting. I saw some much less eloquent ways of doing this on other posts, but plan to incorporate this.

  11. Nice one! I was thinking about the rollback phase in task sequence and the user notification. If setup kicks a rollback during “winPE” phase then the user cannot see this message because TS ends to logon screen.

  12. If the task sequence detects that the version being upgraded is already installed, what’s the best way to kill the “upgrading” wallpaper and prevent the TS from continuing? I noticed in your example task sequence that if this situation happens it does not fail or complete the task sequence, just continues on, and it also doesn’t kill the custom background.

    1. That should not be the case if the task sequence is configured correctly. In the example, the first step that runs sets that “WindowsVersion” task sequence variable, and the rest of the step groups will only run if the current version does not match the version number you set in the step conditions.

  13. Trevor – what Chris said basically. In the Section ‘Windows Version Check’, if its already at 1709 it will set that TS variable and all subsequent steps in that section will run with that variable set. However, there is not step to fail it out. We had to add a fail step, basically copying other ‘Fail TS with OS Upgrade return code’ steps. Its fine now, just wanted to let you know your TS.xml is missing a fail step in the initial windows os check. Other than that, we find this solution very valuable and are going to be using it for our enterprise!

  14. Are there any prerequisites that apply? To test the window pop functionality, I have used your TS with your scripts in a package. Changed the condition on all steps for version 1703 as that is our current version. I was testing only the window pop if Windows version is same. It appears to run as I see a brief powershell window and then no message window pop. I tested the logic using psexec64.exe -s calling powershell and all the required switches. It too failed.

  15. Thank you for all your work on this Trevor. It’s been very helpful. I’ve been testing this on some HyperV VM’s running 1511 and 1607, using it (modified) to upgrade to 1703 (that’s the most recent version allowed in our org). I’m having mixed results however. It’s worked on a couple VM’s without issue (so I’m pretty sure I didn’t break anything with my modifications) however on most of my tests, the upgrade fails right after the first reboot, and the system boots back to it’s original OS with the error code “the upgrade to Windows 10 x64 1703 could not complete. Windows setup returned the following code. 0xd1900107.

    Googling this error hasn’t given me any good clues to go off of. 2 of these machines are absolutely clean installed version of 1511, and the others are our base company image of 1607 with Feb 2018 updates installed. Does this error mean anything to you?

  16. You ever see the OS upgrade throw a exit code of 3247440400 instead of 0? That happened to multiple systems today. 3247440400 is supposed to be the code from the upgrade assessment. It also rolled back the OS too, so not sure why the failure group ran that was only supposed to run if SMSTSSetupRollback did not equal true.

  17. This is fantastic stuff!

    I’ve noticed that when we try this on 1709 devices it prompts that they are already on 1709 like it should… and then it closes the Software Center but maybe 30 minutes or so later it ended up giving a countdown to a reboot and ended up rebooting the device and running the upgrade to 1709 on the device again.

    Is there something that I’m missing?

  18. Hey Trevor, this is awesome stuff but I’ve run into an interesting issue.

    I’m attempting to create a custom message using stackpanels and dockpanels using New-WPFMessageBox. For some reason the script runs perfectly when ran manually. But when ran in a TS (With Invoke-PSScriptAsUser.ps1) the window does not appear at all and the TS completes with no errors. It appears that using a Stack Panel is the culprit as swapping to the $Message variable instead of $StackPanel works. The bottom of the code is pasted below, above this is your standard WPFMessageBox code with just a couple functions added. Let me know if you have any ideas. Thanks

    # Read the current _IsOnBattery variable value from file
    $ReadFromRoot = “$env:SystemDrive”
    $ReadFromDirectory = “temp”
    $ReadFromLocation = “$ReadFromRoot\$ReadFromDirectory\”
    $FileName = “_IsOnBattery.txt”
    $BatteryTSV = Get-Content “$ReadFromLocation\$FileName”

    $BatteryTB = New-Object System.Windows.Controls.TextBlock
    $BatteryTB.Text = “Not Using Battery Power”
    $BatteryTB.FontSize = “20”
    $BatteryTB.HorizontalAlignment = “left”
    $BatteryTB.Margin = “20”

    #Set Battery Status
    If ($BatteryTSV -like “True”)
    $BatteryDP = New-Object System.Windows.Controls.DockPanel
    $BatteryDP.LastChildFill = “false”
    $BatteryDP = New-Object System.Windows.Controls.DockPanel
    $BatteryDP.LastChildFill = “false”

    $StackPanel = New-Object System.Windows.Controls.StackPanel

    # Display the message
    #$Message = “hello”
    New-WPFMessageBox -Content $StackPanel -ContentTextForeground Black -ContentFontWeight DemiBold -ContentFontSize 16 -Title “Windows 10 Compatability Results” -TitleFontSize 24 -TitleBackground Green -TitleTextForeground White -Sound ‘Windows Exclamation’

  19. I am trying to create a pause before continuing and not have any success. The idea is that I will have a section run to see if there is USB devices connected and if so prompt to remove them. That code looks like the following. The problem is that the prompt does come up but it still continues onto the next section without a button being clicked.

    $Params = @{
    Content = “Please remove all external storage devices”
    Title = “USB Devices Connected!”
    TitleBackground = “LightGray”
    TitleFontSize = 28
    TitleFontWeight = “Bold”
    TitleTextForeground = “Red”
    ContentFontSize = 18
    ContentFontWeight = “Medium”
    CustomButtons = “Continue”,”Cancel”

    New-WPFMessageBox @Params -ButtonType OK-Cancel
    If ($WPFMessageBoxOutput -eq “OK”)
    $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
    $tsenv.Value(“_SMSTSLastActionRetCode”) = 0
    ElseIf ($WPFMessageBoxOutput -eq “Cancel”)
    $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
    $tsenv.Value(“_SMSTSLastActionRetCode”) = 1

    Is this the best way to go about this?

    1. Yeah the way the code is called into the user context does not wait for any response. So to achieve that you would need to identify the PowerShell process that was created and wait for it to exit. There is a WaitForExit() function on a process object in .Net. Run that either in the script that invokes the user-context script, or in the TS step immediately after.

  20. Trevor,

    Great stuff, thank you for making this available! I’ve got a great looking F12 OSD TS but until I came across this, my upgrade TS wasn’t really making me happy, I love the validation check and custom background. I do have an issue with the background though, it doesn’t display in 50% of cases, it is invoked, I see the tslog shows it was launched and returned a “0” exit code but I see nothing, I have seen it work as expected on some upgrades, so it seems some local condition exists that prevents it from instantiating? Any ideas on what to look for to trap?



    1. Thanks for the feedback. I haven’t tested this extensively but since the background uses WPF it probably requires a minimum PS version of 3 (preferably 4+) and .Net framework 4.5

      1. These are all fresh W10 1709 machines being tested for the 1803 upgrade, nothing else, so I know the pre-reqs must be correct. Seems like a sporadic problem that’s more prevalent on slower VM’s, I haven’t yet seen a physical machine fail but 80% of my testing has been in the VM lab. Will the graphic still display if no user is logged on when it’s invoked, but rather say 5 or 10 minutes later, is a logged on user required for the script to display a BG?

  21. Thanks Trevor for a great description. However, I still have a problem in the section: “Check Readiness for Upgrade”.

    After importing your task sequences in SCCM, “Ensure minimum free disk space (MB)” wasn’t marked. I did mark it, but when there is less space on the computer that the minimum required, user gets error from sccm (0x80004005) and not a message from the script…

    You wrote in the description ” Where the compatibility scan or OS upgrade fails, the step is set to continue on error so that we can handle the error ourselves”, so for „Check Readiness for Upgrade” I marked „Continue on error” because it wasn’t marked.
    After this procedure no message was displayed and the OS upgrade process is continuing, but it shuldn’t (no required amount of disk space).

    Could you advise what is the reason messages do not appear?

  22. Great work Trevor!
    I seem to be missing something with using the existing process, but modifying it to upgrade to 1803. The 1709 upgrade works great as you described, but when I make the change to the TS to instead, use build 1803, the target machines say that they are already running 1803, when in fact they are running 1709. Anything I should look for?

    1. Trevor one more question, at the moment message appears, install continue without interruption, my aim prevent unexpected reboot while in-place upgrade…. do you have any ideas?

  23. Hey Trevor,

    Is there a reason you aren’t using serviceui.exe to launch the message boxes? This would allow the message scripts to read and create Task Sequence variables and not require the middle man files, since serviceui.exe launches the script in the system context and still allows user interaction

  24. Hey Trevor,

    Great stuff. Most part seems to be working fine but I running into one specific issue. Upon successful upgrade from Win 7 to Win 10 1803, after few minutes of logon, the upgrade TS kicks in again and starts the deployment again. Also the status icon of TS remains as new. Although it doesn’t do anything, but in software center, under OS , is keeps spinning with status Installing. Any clue why it would do so ? I know removing it from the collection will do the trick but that would not always be case.

  25. This is so great – I’ve implemented it in our task sequence and I love the notifications and the look and feel. Kudos.

    Do you know if there is a way to make these popups happen even if the computer is locked? Right off the bat, we restart the computer as part of the task sequence, so if the user doesn’t log in right away they miss the prompt. Logging in after the task for showing the upgrade in progress message causes the user to get no notification.

    1. Not for this solution, you’d need to run the splash screen as a service. You could check out the solution from OneVinn which does something similar and does run as a service.

  26. Trevor, potentially a goofy question. I’m trying to extend the wpf-messagebox a bit and would like to implement a countdown timer. I know the about the timeout param for it but I’d like to be able to display a countdown as part of the message. Is this something that’s even possible?

  27. Hey Trevor,

    Do you have a way to show notifications to users if the OS upgrade failed but they weren’t logged in at the time? Invoke-PSScriptAsUser.ps1 seems to only work if they are logged in, and I tried your Active Setup method but that seems to not work if the OS didn’t get upgraded.

  28. Hi Trevor,
    I’d like to use your scripts… but…
    any clue why the Invoke-PSScriptAsUser.ps1 … always fails with
    “StartProcessAsCurrentUser: GetSessionUserToken failed.” ?

    Thanks! Mike

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.