En titt på PowerShell Application Deployment Toolkit

Ganska ofta när man sysslar med ”application deployment” uppstår lite mer avancerade behov än vad applikationens installationsprogram klarar. Typiskt sett innebär det att man ofta vill göra något på datorn innan installationen startar och/eller efter att installationen är färdig. Några vanliga exempel kan vara:

  • Ställa om en terminal server till installationsläge
  • Skapa eller ta bort genvägar till applikationen (när man inte kan eller orkar redigera själva installationspaketet)
  • Avinstallera gamla versioner av applikationen
  • Stänga applikationer som är igång på datorn och som hindrar installationen
  • Utföra någonting på en server (i typiska client/server-applikationer) såsom att registrera klienten i någon databas eller några andra dumheter som utvecklarna har hittat på

Lösningen på detta är att man använder en s.k. ”wrapper”, det vill säga ett script som startar själva installationsprogrammet men också innehåller kod för att göra allt det andra.

Jag har under ett antal månader arbetat en hel del med verktyget PowerShell Application Deployment Toolkit som är skapat just för det här ändamålet och som dessutom är gratis och open source, och som namnet antyder helt baserat på PowerShell.

Verktyget finns att ladda ned från CodePlex här: http://psappdeploytoolkit.codeplex.com/

I början var det ganska buggigt, men nu fungerar det riktigt bra och har snabbt blivit ett av mina standardverktyg som jag använder just för alla lite mer avancerade applikationsbehov. Jag har själv försökt bidra en del till projektet med bl.a. diverse buggfixar, svensk översättning och betatestning.

Så låt oss ta en titt på vad man kan göra med detta trevliga verktyg.

Funktionalitet

GUI

Vi får ett GUI som vi kan välja att visa för användaren när en installation startar, körs och avslutas. Vi kan ge användaren möjlighet att skjuta upp installationen x antal gånger under en viss tidsperiod, eller så kan vi använda oss av en nedräkning innan installationen startar, osv. En mycket trevlig funktion här är att vi har stöd för flera språk, så all text visas automatiskt på det språk som är valt i Windows. Ett antal språk följer med från början, däribland svenska (skyll på mig om du inte gillar översättningen, det är nämligen jag som har gjort den :)) men vill du lägga till ett nytt språk eller ändra någonting i texterna så är det enkelt. Allting ligger nämligen i en xml-fil. Vidare kan vi även personifiera utseendet enkelt genom att lägga till en egen logga, det är bara att byta ut en bildfil.

PS-App-Deploy-Toolkit-GUI
Exempel på dialogruta som visas för användaren

 

Blockering och stängning av applikationer

Här har vi hela huvudanledningen till att jag personligen började använda detta toolkit. Vi kan alltså stänga ned applikationer som igång på datorn och som hindrar installationen. Det är framförallt här det är trevligt med ett GUI så att vi kan varna användaren att en viss applikation kommer att stängas, och om vi så vill ge denne möjlighet att skjuta upp installationen. Inte nog med det, vi kan blockera applikationen från att startas under tiden som installationen pågår, så att den klåfingriga användaren inte drar igång den direkt efter att den stängts ned och därmed pajar allting ändå. Det finns diverse smart logik här som gör att det hela fungerar bra, som t.ex. en städningsrutin om datorn skulle stängas av mitt under installationen så kommer blockeringen att tas bort automatiskt vid uppstart och inte blockeras igen förrän installationen startar nästa gång.

Stöd för SCCM

Eftersom man naturligtvis använder SCCM (vad annars?) för att hantera sina applikationer är det viktigt att verktyget fungerar bra tillsammans med SCCM. Även om det är egentligen inte är några större konstigheter då SCCM sällan bryr sig om så mycket annat än att den kan exekvera ett kommando, så är det ändå skönt att veta att PS App Deployment Toolkit utvecklades med just SCCM i åtanke. Man har t.ex. tänkt på att man ska kunna göra både installation och avinstallation med samma script så att vi enkelt kan utnyttja detta i Applications, och exit koder hanteras bra, som t.ex. Fast Retry (1618) och Reboot (3010). Vidare känner verktyget automatiskt av om installationen körs av en task sequence eller utan att någon användare är inloggad på datorn, och kommer isåfall inte visa något GUI. Mer om detta längre ned.

Övrigt

Det finns en lång rad små smarta funktioner du kan använda direkt i scriptet, och räcker inte dessa så är det bara att lägga till egna Powershell kommandon eller exekvera andra verktyg eller vad du nu vill göra. Några exempel på inbyggda funktioner:

  • Kontrollera diskutrymme som krävs för installationen och meddela användaren om det inte räcker till
  • Läsa innehåll i ini-filer
  • Söka efter installerade applikationer på datorn
  • Avinstallera applikationer på datorn baserat på namnmatchning (”Java” kommer t.ex. avinstallera alla applikationer som innehåller namnet Java)
  • Trigga SCCM tasks, som t.ex. att göra en hardware inventory efter installationen
  • Skapa/ta bort genvägar på t.ex. skrivbordet och/eller ”pinna” dessa på ”taskbar”
  • Skapa registernycklar
  • Uppdatera group policy

Och mycket annat.

Hur det funkar

När du laddar ned och packar upp PS App Deployment Toolkit får du en mapp som innehåller tre undermappar. I toppmappen ligger också följande två filer:

Deploy-Application.ps1 – Det här är scriptet som gör själva installationen av applikationen. Det är här du gör alla ändringar som är specifika för varje applikation. Scriptet innehåller fyra avsnitt: PRE-INSTALLATION, INSTALLATION, POST-INSTALLATION och UNINSTALLATION. Under respektive avsnitt anger man kommandon för att utföra installation och avinstallation samt vad som ska ske före och efter installationen. Vidare kan du skriva in lite information om själva applikationen som installeras, såsom namn och version osv. Viss del av denna information kommer att visas i det GUI som presenteras för användaren.

Deploy-Application.exe – Denna fil har som enda syfte att exekvera scriptet Deploy-Application.ps1, men utan att öppna ett Powershell konsolfönster. Det är den här filen du anger som installationskommando i dina SCCM-applikationer.

De tre katalogerna är följande:

AppDeployToolkit – Här ligger huvudfilerna i verktyget som används av Deploy-Application.ps1.

Files – I denna katalog lägger du installationsfilerna för applikationen som ska installeras. Mappen är tom från början.

SupportFiles – Här kan du lägga eventuella andra filer/script/verktyg som du vill använda under installationen. Mappen är tom från början.

Huvudfilerna som alltså ligger i katalogen AppDeployToolkit är följande:

AppDeployToolkitMain.ps1 – Huvudscriptet som innehåller all logik och alla funktioner som används under installationen. Detta script används av Deploy-Application.ps1-scriptet.

AppDeployToolkitConfig.xml – Här i ligger bl.a. alla texter som visas i det GUI som presenteras för användaren, med översättningar för de språk som följer med. Vill du ändra någon av texterna eller översätta till ett nytt språk så är det bara att redigera denna fil.

AppDeployToolkitExtensions.ps1 – All egen eventuell PowerShell-kod du vill skriva kan du lägga i det här scriptet och det kommer automatiskt att användas av Deploy-Application.ps1.

AppDeployToolkitHelp.ps1 – En hjälpfil som grafiskt visar och förklarar alla funktioner i verktyget.

AppDeployToolkitBanner.png – Detta är den bild som visas i ”bannern” högst upp i i rutan som visas för användaren. Den kan du alltså byta ut mot ditt eget företags logotype eller vad du vill.

AppDeployToolkitLogo.ico – Ikonfil som visas uppe i hörnet i användarens GUI. Även denna kan du byta ut om du vill.

Så processen för att installera en applikation med PS App Deployment Toolkit och SCCM är typiskt sett följande:

  1. Skapa en ny mapp för applikationen och kopiera dit alla filerna och mappstrukturen för verktyget. Kopiera in källfilerna för applikationen under mappen Files.
  2. Redigera Deploy-Application.ps1 och ange som minimum kommandot för att exekvera själva installationen (typiskt sett ett MSI-paket eller liknande) och eventuellt vad som ska ske före och efter installationen.
  3. Skapa en ny Application i SCCM med mappen du skapade ovan som källkatalog. Ange Deploy-Application.exe som installationskommando och Deploy-Application.exe Uninstall som avinstallationskommando.

När du laddar ned verktyget så medföljer en utmärkt guide som beskriver hur allting fungerar mycket mer i detalj.

PS-App-Deploy-Toolkit-Folders
Innehållet i verktyget

Session 0 problematiken

Som standard så döljer ju SCCM all form av GUI som visas av applikationsinstallationer. Men då en stor poäng med att man vill använda PS App Deployment Toolkit är just att kunna visa dialogrutor för användaren som varnar dem för att applikationer måste stängas osv, så måste vi se till att SCCM tillåter detta. Här finns en liten komplikation p.g.a. en fullständigt helidiotisk begränsning i SCCM. Det går nämligen utmärkt att göra detta med gamla klassiska Packages/Programs, men inte lika bra med nya modellen Applications (som vi ju såklart föredrar p.g.a. alla fördelar man får där).

Först lite kort teknisk bakgrund till hur det fungerar.
Från och med Vista och framåt så infördes en ny säkerhetsmodell i Windows, som innebär att systemtjänster (services) körs under en egen session kallad Session 0. När en användare loggar in tilldelas denna en högre session (session 1 och uppåt) och alla applikationer och processer som startas körs under användarens session. Just session 0 är dock alltså speciell från och med Vista då den är isolerad (kallas ”Session 0 isolation”) just för att skydda systemtjänsterna. En del av denna isolering innebär att ingenting som körs under session 0 kan presentera något som helst gränssnitt på skärmen.

SCCM-klienten består som bekant av en tjänst (”SMS Agent Host”) som körs av ”Local System” i Windows. SCCM kan antingen exekvera installationer under session 0, varpå inga dialogrutor eller någonting visas på skärmen, eller under den inloggade användarens session, då dialogrutor kan tillåtas att visas. Notera att detta inte påverkar några behörigheter, det är fortfarande ”Local System” som kör installationen oavsett vilken session den startar i, så länge vi inte aktivt väljer att köra med användarens konto istället.

För båda dessa inställningar, vilken session och vilken användare som ska köra installationen, kan vi alltså konfigurera för varje applikation vi distribuerar med SCCM. Med ett Package/Program gör vi detta under programmets egenskaper under fliken Environment. Om vi kryssar i rutan Allow users to interact with this program så kommer alltså installationen köras under användarens session, och dialogrutor tillåtas att visas.

Med en Application gör vi detta under vår Deployment Type i fliken User Experience. Här finns motsvarande kryssruta som heter nästan likadant: Allow users to view and interact with the program installation. Men nu kommer vi alltså till den korkade begränsningen. Microsoft är så fullkomligt insnöade på att Applications alltid ska installeras mot en användare att man har missat att ge oss möjligheten att aktivera den här inställningen om man samtidigt vill att installationen ska kunna köras oavsett om någon är inloggad på datorn eller inte. Alltså, om vi väljer alternativet Logon requirement: Whether or not a user is logged on så blir genast alternativet Allow users to view and interact with the program installation gråmarkerat och går inte längre att välja. Det här är naturligtvis fullständigt jubelidiotiskt i de fall när vi vill rikta installationen mot datorer, vilket fortfarande är det absolut vanligaste i de flesta företag, och framförallt för basapplikationer som t.ex. Flash player, Java osv.

Packages/programs har inte denna begränsning. Vi måste alltså välja mellan att använda denna äldre och sämre modell, och gå miste om alla underbara funktioner i Applications, eller försöka gå runt denna begränsning på något sätt. Vi kan göra på många olika sätt som att t.ex. använda oss av flera Deployment Types, eller bara rikta installationer mot användare, men inget av detta blir riktigt lika bra som om vi faktiskt skulle ha samma möjlighet som ett traditionellt Package.

SCCM-Program-Environment
Valmöjligheterna för ett ”Program”
SCCM-App-DT-UE
Samma alternativ för en Application, men med korkad begränsning

Lösningen

Det går faktiskt att rent programmatiskt bryta sig ut ur session 0 isoleringen och få fram ett GUI från en process som startats där. Vi försökte under en period lösa detta på olika sätt direkt i PS App Deployment Toolkit, och jag samarbetade tillsammans med utvecklarna för att försöka få med denna funktion. Ett tag såg det ut som om vi lyckades och under några versioner av verktyget fanns denna funktion med. Men sen upptäcktes det att det tyvärr inte fungerade helt bra i alla scenarion, så utvecklarna har tills vidare tagit bort den här möjligheten.

Lösningen är istället att använda ett till litet verktyg, en liten exe-fil från Microsoft som är skapad för exakt detta ändamål. Filen heter ServiceUI.exe, är ca 70 kb stor, och följer med Microsoft Deployment Toolkit. Så vi plockar helt enkelt denna lilla fil från MDT och lägger med den i installationskatalogen för varje applikation. Sen ändrar vi installationssträngen för applikationen i SCCM till ServiceUI.exe Deploy-Application.exe och vóila så fungerar det perfekt.

 

Facebooktwitterredditpinterestlinkedinmail

4 kommentarer

Gå direkt till kommentarformuläret

    • baatch on 2015/05/05 at 01:06
    • Svara

    Hej, tack för en grym blogg och guide!

    Funkar ServiceUI.exe fortfarande i senaste 3.6.2? Behöver man ändra något i .ps1 filen? Finns det några kända problem med att använda ServiceUI.exe ? x86 x64 OS osv?

  1. Tack för det. 🙂

    ServiceUI.exe fungerar oberoende vilken version av PS App Deployment Toolkit som används, så ja det funkar fortfarande.

    Andra problem finns dock, jag skulle ljuga om jag sade något annat. På 64-bitars datorer har det alltid till 100% fungerat för mig, i alla olika miljöer där jag kört det (vilket är ganska många vid det här laget). Dock har vissa rapporterat att man fått vissa problem, men då jag aldrig råkat ut för det själv så har jag aldrig haft möjlighet att felsöka orsaken. Jag påstår därför fortfarande att det fungerar 100% säkert när man kör 64-bitars Windows, och gör det inte det så har man något annat problem i sin miljö.

    För 32-bitars Windows fungerar det dock sämre. En mycket lång utläggning om problematiken och olika problem som olika användare upplevt kan du läsa om här: https://psappdeploytoolkit.codeplex.com/discussions/465270

    Ett alternativ till att använda ServiceUI.exe om du fortfarande kör 32-bitars Windows, är att istället använda psexec.exe från Sysinternals. Det fungerar bra.

    • Dan on 2015/06/15 at 08:47
    • Svara

    Jäkla bra guider, Joachim. Istället för att använda ServiceUI.exe för att lösa session 0-problematiken gjorde jag två deployment types. Satte ena att köras ”Only when a user is logged on” och bockade i ”Allow users to view and interact…”, och andra ”Whether or not”. Tricket är att använda requirements (ett global condition) på respektive DT som säger att den bara kan köras ifall någon är inloggad på datorn, eller inte inloggad.

    Så mitt global condition är den här PowerShell-koden:
    $user = query user
    [bool]$user

    Om det ger True är någon inloggad, antingen lokalt eller via RDP/TS, False så är ingen inloggad.

    Lite mer info här:
    https://social.technet.microsoft.com/Forums/en-US/269d0d9c-5d70-4a58-aae9-47ec82f55b5b/creating-a-user-logged-on-or-off-global-condition?forum=configmanagerapps

  2. Tack för din kommentar Dan, och för att du bidrar med en bra lösning. 🙂
    Jag har sett flera gå samma väg och köra dubbla DTs, så det är helt klart ett fungerande alternativ.

Lämna ett svar

Your email address will not be published.

Fyll i svar på den enkla captcha-frågan nedan för att få kommentera * Time limit is exhausted. Please reload CAPTCHA.