Windows 10 Kiosk Mode without Intune – Notes from the field


I was recently tasked with deploying Windows 10 Kiosk Mode for a customer. This is without Intune.

Kiosk Mode can be easily deployed via Intune but if you are not using that as a deployment mechanism then it’s still possible but requires a bit more manual graft. There were some interesting observations along the way so I’ll capture these in this document and hopefully this will help you avoid the pitfalls.

So, the plan was to deploy a multi-app kiosk. Multi-app kiosks are allowed from Windows 10 1709 onward, make sure you have at least this version on your device. I’m going to be mentioning certain baselines here, since certain features are only allowed for certain baselines or simply because I had problems and the fixes were to deploy a particular release or hotfix. Make sure, also, that you are running either the Enterprise, Education, Pro or S SKU. Windows 10 Home is not supported.

Kiosks use the Assigned Access CSP feature and you can read about this here. Applications can be either Win32 apps or UWP apps. For UWP apps you must provide the App User Model ID (AUMID) and for Win32 apps the full path of the executable file in your allowed apps list and we’ll take a look at this shortly.

The basics of kiosk mode are that we must create a XML file which will contain a profile or set of profiles which are assigned to configs. The wording from Microsoft is as such:

  • A configuration xml can define multiple profiles. Each profile has a unique Id and defines a set of applications that are allowed to run, whether the taskbar is visible, and can include a custom Start layout.
  • A configuration xml can have multiple config sections. Each config section associates a non-admin user account to a default profile Id.
  • Multiple config sections can be associated to the same profile.
  • A profile has no effect if it’s not associated to a config section.

For the example here, we are going to keep it simple by creating one profile and one config.

Start off by generating a unique GUID which will be used to associate the profile with the config. You can do this online. I’ve used the site https://www.guidgenerator.com/online-guid-generator.aspx.

Now we can start to construct the XML file. Microsoft has lots of examples in their documentation so let’s take an example from there with my generated GUID added.

<?xml version="1.0" encoding="utf-8" ?>
<AssignedAccessConfiguration
    xmlns="https://schemas.microsoft.com/AssignedAccess/2017/config"
    xmlns:rs5="https://schemas.microsoft.com/AssignedAccess/201810/config"
>     <Profiles>
        <Profile Id="{bc38b341-6836-449d-ad4f-49672ab8e8a2}">
            <AllAppsList>
                <AllowedApps>
                    ...
                </AllowedApps>
            </AllAppsList>
            <rs5:FileExplorerNamespaceRestrictions>
                <rs5:AllowedNamespace Name="Downloads"/>
            </rs5:FileExplorerNamespaceRestrictions>
            <StartLayout>
                ...
            </StartLayout>
            <Taskbar ShowTaskbar="true"/>
        </Profile>
    </Profiles>
</AssignedAccessConfiguration>

This example is the basic structure of the <PROFILE> section of the XML. Here assigned apps, start menu layout and Taskbar status can be defined.

Let’s expand this out slightly and add in some detail.

<?xml version="1.0" encoding="utf-8" ?>
<AssignedAccessConfiguration
    xmlns="http://schemas.microsoft.com/AssignedAccess/2017/config"
    xmlns:r1809="http://schemas.microsoft.com/AssignedAccess/201810/config"
>
    <Profiles>
        <Profile Id="{bc38b341-6836-449d-ad4f-49672ab8e8a2}">
            <AllAppsList>
                <AllowedApps>
                    <App DesktopAppPath="C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE" r1809:AutoLaunch="true" />
                    <App DesktopAppPath="C:\Program Files\Internet Explorer\IEXPLORE.EXE" />
                    <App DesktopAppPath="C:\WINDOWS\SYSTEM32\CMD.EXE" />
                </AllowedApps>
            </AllAppsList>
            <StartLayout>
                <![CDATA[<LayoutModificationTemplate xmlns:defaultlayout="http://schemas.microsoft.com/Start/2014/FullDefaultLayout" xmlns:start="http://schemas.microsoft.com/Start/2014/StartLayout" Version="1" xmlns="http://schemas.microsoft.com/Start/2014/LayoutModification">
  <LayoutOptions StartTileGroupCellWidth="6" />
  <DefaultLayoutOverride>
    <StartLayoutCollection>
      <defaultlayout:StartLayout GroupCellWidth="6">
        <start:Group Name="">
          <start:DesktopApplicationTile Size="2x2" Column="0" Row="0" DesktopApplicationID="Microsoft.InternetExplorer.Default"  />
          <start:DesktopApplicationTile Size="2x2" Column="2" Row="0" DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Command Prompt.lnk" />
        </start:Group>
      </defaultlayout:StartLayout>
    </StartLayoutCollection>
  </DefaultLayoutOverride>
</LayoutModificationTemplate>
                ]]>
            </StartLayout>
            <Taskbar ShowTaskbar="true"/>
        </Profile>
    </Profiles>
    <Configs>
        <Config>
            <Account>temp</Account>
            <DefaultProfile Id="{bc38b341-6836-449d-ad4f-49672ab8e8a2}"/>
        </Config>
    </Configs>
</AssignedAccessConfiguration>

So what’s been added here?

Well I want to allow Internet Explorer and CMD to run on my kiosk. So I have defined these in the AllowedApps tags. For Internet Explorer I have also set the command parameter r1809:AutoLaunch=”true”. This is a new feature from Windows 10 1809, the ability to auto launch an app. You also have to add the line xmlns:r1809=”http://schemas.microsoft.com/AssignedAccess/201810/config&#8221; in the <AssignedAccessConfiguration> section of the XML.

Note from the field – take a look at the code in the example from Microsoft and compare with what I have added. xmlns:rs5= or xmlns:r1809= ? Well MS has mixed messages since their documentation references each but xmlns:r1809= is the one to use. They need to update their documentation to reflect this.

Note from the field – I’ve had zero success autolaunching when using Windows 10 1809, even though the code is written for it. Maybe I needed a hotfix but nothing is stated. In the end, I pushed 1903 out to the endpoint and the code works perfectly.

What else is happening in the code? Well I have set a Start Menu to display my IE and CMD shortcuts and I’m allowing the taskbar to be shown.

I’ve also created the <CONFIG> section and in this I am creating a link between the <CONFIG> and <PROFILE> section via DefaultProfile Id=. The GUID matches that of the Profile Id= in the <PROFILE> section. Therefore, the account associated with the <CONFIG> will have the <PROFILE> settings applied to it when logged in.

I have referenced a local account in the <ACCOUNT> tag, <Account>temp</Account>, however this can be a domain account, reference with domain\account or an Azure AD account.

Note from the field – when applying the XML the account must exist for the XML to apply successfully.

There is other functionality which you can add to the XML, such as configuring automatic logon, changing the display name which appears when logging in or allowing access to the Download folder for storage. As I say, I’m keeping this simple and showing you the basics to get up and running. Check out Set up a multi-app kiosk  for more tips

With our XML ready to go we can apply the code by wrapping this in PowerShell and using the MDM bridge to apply.

So we enter

$nameSpaceName="root\cimv2\mdm\dmmap"
$className="MDM_AssignedAccess"
$obj = Get-CimInstance -Namespace $namespaceName -ClassName $className
Add-Type -AssemblyName System.Web
$obj.Configuration = [System.Web.HttpUtility]::HtmlEncode(@"
<OUR XML CODE>
"@)
Set-CimInstance -CimInstance $obj

Here’s my example. You can download the code from here:

$nameSpaceName="root\cimv2\mdm\dmmap"
$className="MDM_AssignedAccess"
$obj = Get-CimInstance -Namespace $namespaceName -ClassName $className
Add-Type -AssemblyName System.Web
$obj.Configuration = [System.Web.HttpUtility]::HtmlEncode(@"
<?xml version="1.0" encoding="utf-8" ?>
<AssignedAccessConfiguration
    xmlns="http://schemas.microsoft.com/AssignedAccess/2017/config"
    xmlns:r1809="http://schemas.microsoft.com/AssignedAccess/201810/config"
>
    <Profiles>
        <Profile Id="{bc38b341-6836-449d-ad4f-49672ab8e8a2}">
            <AllAppsList>
                <AllowedApps>
                    <App DesktopAppPath="C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE" r1809:AutoLaunch="true" />
                    <App DesktopAppPath="C:\Program Files\Internet Explorer\IEXPLORE.EXE" />
                    <App DesktopAppPath="C:\WINDOWS\SYSTEM32\CMD.EXE" />
                </AllowedApps>
            </AllAppsList>
            <StartLayout>
                <![CDATA[<LayoutModificationTemplate xmlns:defaultlayout="http://schemas.microsoft.com/Start/2014/FullDefaultLayout" xmlns:start="http://schemas.microsoft.com/Start/2014/StartLayout" Version="1" xmlns="http://schemas.microsoft.com/Start/2014/LayoutModification">
  <LayoutOptions StartTileGroupCellWidth="6" />
  <DefaultLayoutOverride>
    <StartLayoutCollection>
      <defaultlayout:StartLayout GroupCellWidth="6">
        <start:Group Name="">
          <start:DesktopApplicationTile Size="2x2" Column="0" Row="0" DesktopApplicationID="Microsoft.InternetExplorer.Default"  />
          <start:DesktopApplicationTile Size="2x2" Column="2" Row="0" DesktopApplicationLinkPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Command Prompt.lnk" />
        </start:Group>
      </defaultlayout:StartLayout>
    </StartLayoutCollection>
  </DefaultLayoutOverride>
</LayoutModificationTemplate>
                ]]>
            </StartLayout>
            <Taskbar ShowTaskbar="true"/>
        </Profile>
    </Profiles>
    <Configs>
        <Config>
            <Account>temp</Account>
            <DefaultProfile Id="{bc38b341-6836-449d-ad4f-49672ab8e8a2}"/>
        </Config>
    </Configs>
</AssignedAccessConfiguration>
"@)
Set-CimInstance -CimInstance $obj

To inject this, we need to be running as SYSTEM. If you are using ConfigMgr to apply the PowerShell then this is nice and simple as you can simply deploy out in your Task Sequence as a Run PowerShell script step.

To manually do it follow these steps:

  • Grab a copy of PSTools
  • From an administrator CMD prompt run PSEXEC -i -s cmd to launch CMD as SYSTEM.

A quick whoami will confirm you are running as SYSTEM

Launch PowerShell from CMD and Set-ExecutionPolicy Unrestricted. Then run the PS1 script containing the code. If you get an error you may need to validate your code. As I mentioned earlier, make sure your account exists or can be referenced.

I’m using the local temp account but it’s not been defined.

After creating the account I can inject the PS1 code successfully.

You can use the first three lines of the PS1 script to query the AssignedAccess MDM to ensure that the code has been injected OK, or if you update the code and re-inject and need to check your changes have been accepted.

Check the $Obj variable to confirm.

Now when logging in as the assigned user the lockdowns and assigned access will take effect.

If anything fails to run check the AppLocker logon the device for blocks and update your XML file with the correct details.

Note from the field – There is a bug with printing from IE and you must run Windows 10 1903 with latest October KB’s to fix the problem. The error reports as a block in policy. The problem is also resolved in Windows 10 1909.

Note from the field – AppLocker blocked me from running CMD from anywhere except from the Start Menu tile, which points to the location %APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Command Prompt.lnk. i was attempting to run the shortcut to CMD from another location on the c: drive. Not sure why this happened. Most kiosks wouldn’t want to allow CMD in the first instance but this was something I noted as part of my testing. Be aware.

With everything up and running you’ll have a locked down kiosk in full effect.

Feel free to comment with your experiences and let me know how you got on with adding in auto logon, folder access and more.

61 comments

  1. Excellent post and very handy. 2 quick questions.
    1. I would like apply screen saver for the Multi-app KIOSK section. Any idea to do so?
    2. How to remove all the Multi-app KIOSK setting?
    Thanks.

    1. Ronald
      1. You can apply the screensaver as normal to the device and use GPO to assign it. I was happily running a .scr file in my multi-app kiosk
      2. I’m sure I read some MS docs on how to remove the assigned access XML but I’ve not been able to find them again since doing so. MS do state though, that due to the nature of the applied settings, then a factory reset of the device is the only way to get rid of all the settings and policies.

      1. No possible at present. An option would be to just apply the GPO’s which kiosk mode utilises, create your own AppLocker policies and not apply the AssignedAccess. Cheers Paul

  2. Hello,
    Firstly, I’d like to say thank you for the post as it was an interesting read.
    Secondly, I’d like to address potential security leaks.

    0.) The Use of PSExec
    — This is old and a security nightmare.
    — Consider switching to PSRemoting. https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/running-remote-commands
    — If it’s ABSOLUTELY necessary as one time use, PSExec shouldn’t be all to bad. Just remember to lock your Admin$ and C$ shares after.

    1.) Powershell Execution Policy
    — You don’t have to set the global execution policy to unrestricted.
    — This can (and most likely will) be forgotten and any malicious scripts can be ran at free range.
    — Instead use the following;
    — powershell.exe -ExecutionPolicy Bypass -File .\KioskXML.ps1

    Thirdly, no need to visit a 3rd party website for GUID generation. You can use powershell to do this!
    In powershell, type the following;
    [guid]::NewGuid() | Select -Property guid -ExpandProperty guid | Set-Clipboard

    Conclusion,
    Thanks for the article as it was helpful to understand how to run this without the use of Intune.
    I was able to successfully run this on one of my labs.

    Thank you and Happy Holidays!

    1. Thanks for this info IT Guy. Worth noting that the method to run psexec is taken direct from MS docs. I’m only doing this to manually apply the ps script when testing but using MEMCM. via a TS to actually apply the script and using the bypass parameter 😉 Cheers Paul

  3. I copied your code and created a test profile to test. I ran the script according to the directions you provided and I am getting the following error:

    The property ‘Configuration’ cannot be found on this object. Verify that the
    property exists and can be set.
    At line:5 char:1
    + $obj.Configuration = [System.Web.HttpUtility]::HtmlEncode(@”
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

    Set-CimInstance : Cannot bind argument to parameter ‘InputObject’ because it is
    null.
    At line:60 char:30
    + Set-CimInstance -CimInstance $obj
    + ~~~~
    + CategoryInfo : InvalidData: (:) [Set-CimInstance], ParameterBind
    ingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Mi
    crosoft.Management.Infrastructure.CimCmdlets.SetCimInstanceCommand

    When I the $obj variable in powershell I do not get any configurations as you did in your example. Can you offer some advice on this issue?

    I am using Win 10, 1809.

    Thanks

      1. Thank you for the quick reply. I will try it on the 1903 image and see what results I get.

      2. Cheers Steven. I know there are certain things which worked out of the box for us in 1903 which didn’t in 1809 – such as the autolaunch. I’d be interested to see where you get with this.

  4. Hello!
    I’m trying to follow your instructions in this post but i have problems importing code into $obj.
    Pwershell dont recognize as html code. It is importing as < and other characters like \ or ” arent imported.

    Can u help me to know the reason?

    Thanks

  5. Sorry, various missclicks in my last comment.


    Hello!
    I’m trying to follow your instructions in this post but i have problems importing code into $obj.
    Pwershell dont recognize as html code. It is importing .\import.ps1
    Set-CimInstance : A general error occurred that is not covered by a more specific error code.
    At C:\temp\kiosk\import.ps1:54 char:1
    + Set-CimInstance -CimInstance $obj
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (MDM_AssignedAcc…./Vendor/MSFT”):CimInstance) [Set-CimInstance], CimException
    + FullyQualifiedErrorId : MI RESULT 1,Microsoft.Management.Infrastructure.CimCmdlets.SetCimInstanceCommand

    Thats my $obj:
    $obj

    Configuration :

    <![CDATA[

    ]]>

    Customer

    InstanceID : AssignedAccess
    KioskModeApp :
    ParentID : ./Vendor/MSFT
    ShellLauncher :
    PSComputerName :

  6. Great Post Paul, I am very grateful for it, thanks.
    There is only one thing I can not setup… as I see on your screenshot, that you could hide the “All programs” button on the upper left corner. I used your ps1 content, but somehow it is still available.
    Did you use GPO or something else to hide it?
    Thanks again,
    Laszlo

      1. OK I’ve replicated this on Win 10 2004. I can’t see anything in the docs which state how you can remove this and it’s a poor experience when you click it as well. Let me message Microsoft and see if this can be removed at all. Cheers Paul

  7. I’m having some problems, the script takes an extended period of time to run, then once finished I find that the $obj contains nothing for the configuration value, with only the InstanceID and ParentID values present.

    Any idea what might be going wrong?

    Thanks.

    1. Brian, what Windows 10 baseline? I’ve not tested on 1909 or 2004 so if one of those, let me know and I’ll test it to see if I can replicate the problem. Code does change with baseline releases. Cheers Paul

  8. Hello!
    Great post I am very thankful.
    Tested it on Win10 Pro 1909 and it works.

    The only problem I am having is when I add an exe’s path to AllowedApps it does not work if the path is UNC.

    I have tried network mapping and even with assigned letter R:\qwe.EXE did not work.

    Any clue?

    Thanks,
    Luka

    1. HI Luka, IIRC mapped drive and UNC locaitons not allowed in the AllowedApp list. However in my instance, I was able to use an allowed app from the C: drive that called remote executables if that is something you can try out as a workaround. Cheers Paul

      1. Hi Paul,

        thanks for fast reply.

        I have tried using start-process with remote exe path and then converted .ps1 file to .exe with ps2exe and added exe to the list. Still not working, exe runs fine but errors out as blocked exe.

        Do you know any other way to hide remote exe?

        Thanks!
        Luka

      2. Hi Paul!

        I have found a solution.
        I run remote file as different user and it works.
        Not the best solution but it does its job.

        Thanks for pointing me in the right direction.

        Cheers Luka

  9. Hello Paul,

    I downloaded the PS script and tried to run it. I get the following error :
    The property ‘Configuration’ cannot be found on this object. Verify that the property exists and can be set.
    At C:\Users\Wartung\Desktop\IEKiosk.ps1:5 char:1
    + $obj.Configuration = [System.Web.HttpUtility]::HtmlEncode(@”
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

    Set-CimInstance : Cannot bind argument to parameter ‘InputObject’ because it is null.
    At C:\Users\Wartung\Desktop\IEKiosk.ps1:47 char:30
    + Set-CimInstance -CimInstance $obj
    + ~~~~
    + CategoryInfo : InvalidData: (:) [Set-CimInstance], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.Management.Infrastructure.CimCm
    dlets.SetCimInstanceCommand

    I am using Windows 10 2004 (OS Build 19041.421).

    Do you know why could this be?

    I only modified the username to reflect a local account.

    Thanks!

  10. Thanks SCCMentor for the excellent document. I have successfully configured a multi app KIOSK.

    Now I want to add Downloads folder and when I add the command, (

    )

    I am getting below error.

    Set-CimInstance : A general error occurred that is not covered by a more specific error code.
    At line:1 char:1
    + Set-CimInstance -CimInstance $obj
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (MDM_AssignedAcc…./Vendor/MSFT”):CimInstance) [Set-CimInstance], CimExce
    ption
    + FullyQualifiedErrorId : MI RESULT 1,Microsoft.Management.Infrastructure.CimCmdlets.SetCimInstanceCommand

    OS: Windows10 Enterprise 64bit 2004update

  11. i was trying to use this script on a machine and make it kisok for all the users . but script doesnt seems to be working that way. it only makes kiosk for the account which is mentioned in the script.
    i pushed the script from intune.
    any suggestions how to use this script for all the users

  12. Absolutely excellent article thank you. Got me going much easier than MS’s document.

    When I add a program I wrote and compiled in “C” lets say HelloWorld.exe which displays “Hello World”. I do not get any errors but I just can’t get the icon to show on the Kiosk desktop. I have placed it in every area of the local drive I can think of that should matter. I have no issues with apps from vendors or MS apps, just my own creations. I have tried the full path in each case.

  13. hi, great script and clear instructions, I managed to run them and got in kiosk mode. the exit from kiosk mode script would be nice to have
    my question would be, if you have the knowledge, how to put a hololoens 2 into kiosk mode. the xml is very similar but I cannot get it to run.

  14. HI, I’m sorry I don’t understand the part with “I’m using the local temp account but it’s not been defined.” Must the account be linked to an MS Account or can it be local? I have a local account with admin rights and I’m constantly getting an error:

    Set-CimInstance: A general error occurred that is not covered by a more specific error code.
    At C: \ Users \ kiwik \ Desktop \ IEKiosk.ps1: 47 char: 1
    + Set-CimInstance -CimInstance $ obj
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo: NotSpecified: (MDM_AssignedAcc …. / Vendor / MSFT “): CimInstance) [Set-CimInstance], CimExce
    ption
    + FullyQualifiedErrorId: MI RESULT 1, Microsoft.Management.Infrastructure.CimCmdlets.SetCimInstanceCommand

  15. I’m sorry I don’t understand the part with “I’m using the local temp account but it’s not been defined.” Must the account be linked to an MS Account or can it be local? I have a local account with admin rights and I’m constantly getting an error:

    Set-CimInstance: A general error occurred that is not covered by a more specific error code.
    At C: \ Users \ kiwik \ Desktop \ IEKiosk.ps1: 47 char: 1
    + Set-CimInstance -CimInstance $ obj
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo: NotSpecified: (MDM_AssignedAcc …. / Vendor / MSFT “): CimInstance) [Set-CimInstance], CimExce
    ption
    + FullyQualifiedErrorId: MI RESULT 1, Microsoft.Management.Infrastructure.CimCmdlets.SetCimInstanceCommand

  16. This is beautyful!

    But one Question:
    After Lockdown, the Kiosk User couldn’t change WiFi Settings. Any Workaround for this?
    Thanks in advance,

    Andreas

  17. Anyone have any luck getting Microsoft Edge to auto launch? I have the following:

    on 1909 but not seeing it autolaunch.

  18. So this worked perfectly to set up a kiosk, great guide.
    However something for everyone to be aware of – because Assigned Access enforces Tablet Mode, you can’t have a kiosk with more than one display. Tablet Mode does not support dual displays, when the autologon account attempts to log in, it will be signed out straight away.
    1909 had a workaround where you can unplug the second screen, sign in, then plug it back in and it will allow the screen, but that has been fixed in 2004 and 20H2 and no longer works.

    It appears to be a long standing complaint with MS. Apparently the only solution at present is to manually replicate the actions of Assigned Access (applocker etc), without enforcing Tablet Mode at the end.

    1. Thanks Brian for the comment. Yes this is true tablet mode is enforced. It’s a real pain, as well, when you use a browser in windowed mode as it snaps to specific locations on the screen as dictated by tablet mode. Cheers Paul

  19. Hello Paul,

    Recently we are getting new MSEdge automaticly placed on our taskbar. Is there any way to remove it?
    Its not even in our allowedapps nor in startLayout.

    attached photo:

    Cheers Luka

Leave a Reply to Claudio Cancel reply

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

WordPress.com Logo

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

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s