Automatisk backup av Task Sequences i SCCM

Task Sequences i SCCM är så pass viktigt och känsligt att en extra backuplösning för just Task Sequences är en god idé. Här kommer en guide med tillhörande script för hur man kan ta en automatisk backup av en Task Sequence i samma ögonblick som någon gör en ändring i den. Tanken är att använda en Status Filter Rule som triggas varje gång en Task Sequence ändras. Regeln kör då ett script som exporterar Task Sequencen till en XML-fil, och sen importerar den igen så att man har den enkelt tillgänglig inne i konsolen.

Då man typiskt har fler än en Task Sequence så styr man exakt vilken man vill ta backup på genom att ange Task Sequence ID som en parameter till scriptet. (Vill du ta backup på fler Task Sequences så är det bara att lägga till fler Status Filter Rules eller modifiera scriptet). Scriptet kommer läsa ut vilken Task Sequence som modifierats från det Status Message som triggar regeln, och jämföra med vilken Task Sequence du angett. Om de inte matchar så sker ingen backup. På så vis kan man mecka runt hur mycket man vill i alla Task Sequences man använder för Test osv, utan att bli nedlusad med backuper. Allting loggas också i en loggfil som sparas i samma katalog som XML-filerna.

För att det här ska bli riktigt snyggt bör man använda versionshantering. Så som jag gör är att jag använder ett steg inne i Task Sequencen, av typen ”Set Task Sequence Variable”, där jag sparar ett versionsnummer. Varje gång jag ändrar något i Task Sequencen så uppdaterar jag också versionsnumret. (Jag sparar också versionsnumret i WMI och i registret på alla datorer, så att jag enkelt kan använda detta i inventeringsrapporter och queries, men det är en annan bloggpost). Scriptet förutsätter att det finns ett sådant här steg, och man anger vad man kallat variabeln i en parameter till scriptet.

Jag använder semantic versioning, alltså MAJOR, MINOR, PATCH som versionsnummer, men här brukar jag också lägga till dagens datum, så att jag på ett och samma ställe ser vilket datum ändringen gjordes. Så versionsnumret i mina Task Sequences ser alltså ut så här (exempel):
1.0.0 – 2018-01-01

(En ny MAJOR version brukar jag använda t.ex. när jag börjar med en ny Windows 10 version, eller någon riktigt stor förändring i Task Sequencen. En MINOR version är de vanliga löpande förändringarna, som t.ex. byta ut OS-imagen månadsvis mot en patchad image, eller lägga till ett nytt drivrutinspaket, m.m. Och PATCH är alltså en fix av någonting som är fel och inte fungerar i Task Sequencen).

Scriptet kommer använda detta versionsnummer och lägga till det i namnet på den exporterade XML-filen samt den importerade Task Sequencen. På så vis får vi en snygg och prydlig versionshistorik.

Tips! För att verkligen ha kontroll, använd en enkel change log där ni antecknar exakt vad varje förändring består av.

Steg för steg…

  1. Ladda ned scriptet från Technet Gallery
  2. När scriptet körs kommer alltså vald Task Sequence att först exporteras ut som en XML-fil. Skapa en mapp för detta ändamål på Site Servern, t.ex. C:\TSBackup.
  3. Scriptet kommer också importera in backupen igen till SCCM så att vi enkelt kan se alla våra backuper där. Dessa vill vi ha snyggt och prydligt placerade i en egen mapp. Skapa alltså en sådan under Task Sequences inne i SCCM-konsolen, och kalla den t.ex. Backup.
  4. I den Task Sequence du vill ta backup på, lägg till ett steg av typen Set Task Sequence Variable, som du kallar exempelvis DeployVersion. Värdet du skriver in här är alltså versionsnumret. Varje gång du gör en ändring i Task Sequencen så uppdaterar du alltså detta versionsnummer.

  5. Skapa en Status Filter Rule och kalla den exempelvis Backup Task Sequence. I fältet Component fyller du i Microsoft.ConfigurationManagement.exe och i fältet Message ID fyller du i 30001.

  6. Lägg till en Action i regeln, av typen Run a program. Fyll i följande kommandorad (exempel):

  7. I kommandoraden ovan, ändra parametrarna SiteServer, TaskSequenceID, BackupPath och TSVersionStepName så att de matchar värdena i din miljö. Ändra inte ModifiedTaskSequenceID, här ska det alltså stå %msgis02, som är en variabel som kommer fyllas i från det status message som triggar regeln. (Vill du däremot någon gång köra scriptet manuellt så anger du bara samma värde för ModifiedTaskSequenceID som för TaskSequenceID).

Resultat

Så här kan det se ut när du har använt scriptet ett tag.

Exporterade XML-filer:


All backuphistorik enkelt tillgänglig inne i konsolen:

Facebooktwitterredditpinterestlinkedinmail

SCCM 1610 BIOS till UEFI konvertering misslyckas pga modifierad osdinjection.xml

Bakgrund

I SCCM version 1610 finns en ny och väldigt bra funktion för att konvertera från BIOS till UEFI. Så nu slipper vi använda de osupportade metoder som vi förut varit tvungna att använda. Starkt rekommenderat att prova, om ni inte redan testat detta. Det fungerar hur bra som helst.

Läs mer om hur man gör här: https://docs.microsoft.com/en-us/sccm/osd/deploy-use/task-sequence-steps-to-manage-bios-to-uefi-conversion

För att detta ska fungera krävs att filen bcd-efi-64 (eller bcd-efi-32 för 32-bitars images) finns i boot-imagen.
Vilka filer som skjuts in när man skapar eller uppdaterar en boot-image styrs av filen osdinjection.xml. Det är inte helt ovanligt att man själv modifierar osdinjection.xml, det har länge varit en metod som många använt för att lägga till egna filer som man vill ha med i sin boot-image.

I SCCM 1610 har osdinjection.xml uppdaterats till att inkludera just bcd-efi-64 och bcd-efi-32, varpå alltså denna fil ska skrivas över när man installerar 1610-uppdateringen.

Scenario

Hos en kund idag skulle denna BIOS till UEFI konvertering börja användas, men det fungerade inte. Efter lite felsökning kunde jag konstatera att just bcd-efi-64 saknades i boot-imagen. Detta trots att boot-imagen var helt nyskapad med rätt version. En snabb titt i osdinjection.xml visade att bcd-efi-64 saknades. Den hade alltså inte uppdaterats när 1610 installerats. Tydligen skrivs inte filen över när den befintliga filen är nyare. Den befintliga filen hade modifierats den 27 oktober, och filen i 1610-uppdateringen hade en tidsstämpel från den 26 oktober, alltså äldre.

Lösning

Den enda förändring som görs i nya osdinjection.xml är just filerna bcd-efi-64 och bcd-efi-32. Så lösningen är att antingen skriva in dessa manuellt eller att kopiera över den nya filen. Den nya filen hittas enklast under <installdir>\cd.latest\SMSSETUP\BIN\X64 och filen som SCCM använder ligger under <installdir>\bin\X64.

<installdir> är alltså sökvägen där SCCM är installerat på site servern.

 

Facebooktwitterredditpinterestlinkedinmail

Ny version av SCCM Application Creator

För ett par år sen släppte jag verktyget SCCM 2012 Application Creator, som gör det enkelt att skapa en applikation i SCCM och samtidigt skicka ut den till distributionspunkter, skapa collections, deploya applikationen och allt annat lull-lull som man normalt också gör när man skapar en ny applikation.

Sen dess har det hänt mycket. Vi har fått en ny version av SCCM (Current Branch) och PowerShell-modulen för SCCM, som verktyget är beroende av, har uppdaterats många gånger. Så den gamla versionen av verktyget fungerar helt enkelt inte särskilt bra med nuvarande version av SCCM, och många har efterfrågat ett uppdaterat verktyg.

Idag är jag glad att kunna presentera SCCM Application Creator 2.0 (2012 är borta från namnet), som fungerar utmärkt med senaste versionen av SCCM och tillhörande PowerShell-modul.

Scriptet finns precis som tidigare publicerat på Technet Gallery men nu också på PowerShell Gallery. Så det lättaste sättet att ladda ned scriptet är helt enkelt att använda PowerShellGet (kräver PowerShell 5.0) genom att skriva:

eller

Verktyget är alltså byggt helt och hållet i PowerShell och har ett enkelt grafiskt gränssnitt där man fyller i all information om applikationen.

Scriptet kan göra följande:

  • Skapa en Application i SCCM
  • Skapa en folder och flytta applikationen dit
  • Skapa en MSI deployment type
  • Skapa en App-V 5 (App-V 4 stöds ej) deployment type
  • Skapa en manuell/scriptad deployment type. I det här scenariot måste en detection method manuellt läggas till i efterhand i SCCM konsolen.
  • Distribuera applikationen till en distribution point group
  • Skapa en grupp i Active Directory
  • Skapa en device- eller user collection, antingen tom eller med en membership rule baserad på Active Directory gruppen
  • Skapa en collection folder och flytta collectionen dit
  • Deploya applikationen till collectionen, antingen som Available eller Required
  • Sätta vissa andra inställningar såsom beteende på slow networks eller allow fallback source location, osv

För mer detaljer, och bl.a. om vad exakt som är nytt i den här versionen, kan ni läsa på länkarna ovan till Technet Gallery och PowerShell Gallery.

Verktyget borde vara hyfsat självförklarande, och i hjälptexten i scriptet förklarar allt man behöver veta för att komma igång. Det grafiska gränssnittet är byggt för att vara idiotsäkert så att det inte ska gå att göra fel.

Hoppas det här kan komma till glädje för någon. Ni får jättegärna ge mig feedback om ni gillar det, eller inte gillar det.

SCCMApplicationCreator2.0

 

Facebooktwitterredditpinterestlinkedinmail

Inaktivitet

Det har varit en längre tids inaktivitet här på bloggen. Anledningen är kort och gott att det senaste halvåret eller så har arbetsbelastningen varit extremt hög, och det har inte funnits så mycket utrymme till annat. Med allt nytt och kul som händer i Microsofts värld så räcker dygnets timmar inte till. Det har varit flera stora Windows 10 projekt, några nya Private Cloud/Fabric-implementationer och naturligtvis som vanligt massor med installationer/uppgraderingar/utbildningar av SCCM. Hur kul som helst, men nu får det gärna börja återgå till en lite mer normal nivå, vilket det också så sakta börjar göra. Det betyder att jag äntligen har en och annan kväll eller helg över då man t.ex. kan knåpa ihop något inlägg här på bloggen, och alla andra små projekt som ligger och skaver som dåliga samveten.

Det har börjat bli ganska många som efterfrågar en uppdaterad version av mitt verktyg SCCM Application Creator, som inte har uppdaterats på evigheter nu och inte har hängt med och fungerar med SCCM Current Branch. Jag hoppas nu kunna ta tag i detta relativt snart, även om jag inte vågar lova exakt när. Men det borde inte vara så jättemycket jobb, då jag faktiskt redan skrivit om och uppdaterat verktyget från grunden åt några kunder. Så alla kodförändringar som jag vill ha med finns klara där. Dessa varianter av verktyget är dock just kundanpassade med egna knappar och fält osv för att passa just kundens processer och behov. Så jag behöver alltså bara generalisera koden och ta bort alla kundspecifika grejer, så ska det vara klart. Dock fortfarande inget som görs på en fikarast, men den största delen av arbetet är alltså klart.

Så ha lite tålamod så ska jag verkligen försöka ta mig i kragen snart. 🙂

 

Facebooktwitterredditpinterestlinkedinmail

Varför nya Software Center i SCCM v1511 inte är något att ha (än)

Ingen har väl missat att efterföljaren till SCCM 2012 (R2) är här, och numera heter bara SCCM utan något årtal som versionsnummer. Microsoft har gått över till en löpande servicemodell á la Windows 10, och traditionella uppgraderingar/migreringar är (i alla fall i teorin) ett minne blott.

Den första releasen av nya SCCM har versionsnummer 1511, och en av de mest efterlängtade nyheterna var ett nytt Software Center som kan hantera applikationer som har tillgängliggjorts till användare, och alltså inte bara till datorer.

-ÄNTLIGEN, utropade hela världen. Tills vi upptäckte hur det egentligen fungerade.

Först lite historik.
När man skapar en deployment för en Application eller ett Package och väljer Available, samt riktar installationen mot en device collection, så dyker applikationen upp i användarens Software Center, och användaren kan själv välja att installera programvaran när och om han så önskar. Perfekt, vi kan alltså bygga upp vår företagsinterna ”app store” och erbjuda våra användare en drös med applikationer, utan att de behöver kontakta IT-avdelningen. Vi behöver bara lära dem att de hittar allt de behöver i Software Center.

Men så väljer vi istället att rikta våra installationer mot användare, istället för mot datorer. Vilket kan medföra en viss extra hantering och arbete, men som ändå är otroligt mycket vettigare. Det är ju trots allt människan bakom datorn som ska använda programvaran, och inte datorn själv. Detta är också vad Microsoft har slagit på stora trumman om enda sen SCCM 2012 släpptes. Allting ska vara ”user centric”, och vi ska sluta rikta saker och ting mot datorer och istället sätta användaren i centrum.

Ok så då gör vi en deployment mot en user collection istället och förväntar oss att det naturligtvis ska fungera exakt likadant, dvs att användaren öppnar sitt Software Center och hittar sin applikation där. Men icke. Som vi alla vet så måste man istället installera rollerna Application catalog webservice/website och användaren måste nu istället surfa in på en Silverlight-baserad webbsida. Det finns visserligen en minimal liten länk inne i Software Center som användaren kan klicka på och därmed så öppnas Application Catalog, men det gör knappast saken bättre.

För att göra det ännu sjukare så hanteras egentligen inte applikationen inne i Application Catalog, utan den fungerar bara som en sorts beställningsfunktion (vare sig applikationen kräver ett godkännande eller ej). Efter att användaren valt att installera en applikation så hoppar den nämligen över till Software Center, och det är därifrån man kan följa installationsförloppet, om det gick bra eller dåligt, och även avinstallera applikationen.

VARFÖR i hela världen Microsoft gjorde på detta magiskt dåliga sätt när man byggde SCCM 2012 är okänt. Men att det är korkat och förvirrande är bara förnamnet. När jag håller utbildningar i produkten så är detta ett av de svåraste områdena att förklara för eleverna.

Det vi vill ha är naturligtvis EN plats för alla applikationer, och det var just det vi trodde vi hade fått med nya Software Center i nya SCCM-versionen. Så varför är det då så värdelöst? För att det helt enkelt visade sig vara ett hafsarbete, en otroligt dålig implementation som förmodligen gjorts av en praktikant på en fikarast.

”Nya” Software Center, som har fått ett nytt utseende, exsisterar parallellt med det gamla. Du måste aktivt välja vilket du vill använda med en Client Setting-inställning. Ok, det kan vi väl leva med. Men besvikelsen blev desto större när det visade sig att Application Catalog inte på något sätt försvunnit. Den rollen finns i allra högsta grad kvar, och du måste installera den även om du inte tänker använda webbportalen. Alltså, deployments riktade mot användare hamnar fortfarande i Application Catalog. Nya Software Center är ingenting annat än ett frontend som kan visa de ikoner som alltså i själva verket ligger i Application Catalog.

Det går inte att kalla för någonting annat än en fullösning. Men ok, vi hade kunnat leva med det. Om man bara ägnat ytterligare 5 minuter åt att åtminstone göra detta frontend komplett. Men så är icke fallet.

Följande är vad man kan göra i Application Catalog:

  1. Installera applikationer som är riktade som Available mot en användare.
  2. Beställa applikationer som kräver ett godkännande.
  3. Låta användaren konfigurera User Device Affinity, alltså tala om vilken/vilka datorer han använder oftast.

Av dessa tre funktioner klarar nya Software Center endast en av tre, nämligen den första. Så fort vi konfigurerar en applikation så att den kräver ett godkännande så fungerar det inte längre, och vi måste återigen använda webbportalen. Samma gäller möjligheten att låta användaren kryssa i sina primära enheter.

Men det kanske sämsta av allt är, även den första punkten fungerar bara halvvägs. Allting är frid och fröjd så länge vår applikation alltså inte kräver ett godkännande, men det får inte heller finnas några requirements. Låt oss säga att vi har en applikation med en requirement som säger att den enbart får installeras på användarens primära enhet. Om användaren sitter på en annan dator och surfar in på Application Catalog så kommer applikationen att synas där. Försöker han då installera den kommer ett felmeddelande att visas som talar om att kraven inte uppfylls, och att installationen inte kan fortsätta. Det är inte världens bästa felmeddelande, men det är åtminstone ett meddelande.

Försöker man göra samma sak i nya Software Center istället, så syns inget felmeddelande överhuvudtaget. Applikationen börjar installera och står och snurrar i all evighet, utan att någonting händer eller uppdateras. Klickar man runt i Software Center, eller stänger och öppnar det igen, så försvinner förloppsindikatorn och man kan återigen välja att installera applikationen. För att återigen få se ett snurrande hjul i all oändlighet.

Så kort och gott, har du enbart applikationer som inte kräver godkännande och inga som helst requirements, och inte heller vill låta användaren bestämma sina primära enheter – då kan du börja använda nya Software Center. I annat fall gör du förmodligen bäst i att fortsätta använda gamla Application Catalog, annars riskerar förvirringen bli större än någonsin.

Bitter och besviken? Jajamen. Inte längre förvånad? Nej, tyvärr.
Kommer detta bli bättre? Det hoppas jag verkligen. Klagomålen har varit ganska högljudda och får ganska många röster på Uservoice. Microsoft har nu, i och med den nya modellen för uppdateringar, alla möjligheter i världen att snabbt komma med förbättringar. Och här finns, kan man nog lugnt påstå, en viss förbättringspotential.

 

Facebooktwitterredditpinterestlinkedinmail

Uppföljning: Datorvariabler i SCCM 2012 fungerar inte efter återställning från backup

Det här inlägget är en uppföljning från det tidigare inlägget SCCM 2012: Datorvariabler fungerar inte efter en återställning från backup. Problemet jag beskrev där var hur det blir en mismatch på versionshanteringen för en tabell i databasen då man återställer en backup som innehåller avsevärt färre objekt. Tabellen i fråga berör policies för datorvariabler, och senaste versionen av denna tabell lagras även i registret. När man återställer databasen är alltså värdet annorlunda i registret och databasen, varpå datorvariabler inte kommer fungera förrän databasen har ”kommit ikapp” det värde som står i registret.

Min frågeställning var om detta scenario kan undvikas beroende på hur man gör sin återläsning från backup. I scenariot som min kund hade råkat ut för hade man enbart läst tillbaka databasen, utan att köra setup-programmet för SCCM och välja ”Recover site”.
Jag har nu haft tid att testa igenom lite fler scenarion i min testmiljö för att studera det här lite närmare.

Testscenario och metodik

I min testmiljö skapade jag några datorobjekt och lade till variabler till dem i SCCM-konsolen. Jag höll ögonen på vad som hände i databasen med följande queries:

Dessa queries visar alla datorobjekt som fått en variabel sorterat efter ”rowversion”, det senaste globala rowversion-värdet i databasen, samt vilka datorobjekt som det genererats en policy för, och därmed alltså kommer fungera. Jag kontrollerade också ”Last Row Version”-värdet i registret, som återfinns här:
HKLM\Software\Microsoft\SMS\Components\SMS_Policy_Provicer\MEPHandler som alltså alltid ska matcha det senaste värdet i MEP_MachineExtendedProperties.

Jag provade sedan att skapa 1000 nya datorobjekt i SCCM, och även att importera in 1000 nya användare. Som väntat ökas det globala rowversion-värdet i databasen kraftigt, då alla nya objekt genererar en massa transaktioner i databasen. Jag skapade sen manuellt ytterligare ett datorobjekt och lade till en datorvariabel. Rowversion-värdet för detta datorobjekt i tabellen MEP_MachineExtendedProperties var nu minst 1000 högre än objektet innan, vilket naturligtvis är förväntat. Jag kontrollerade också att värdet sparades även i registret.

Jag testade sedan att återskapa från en backup som jag tog innan jag importerade in mina 1000 objekt. Jag testade de olika supportade varianter som finns för att återställa en SCCM-installation som finns dokumenterade på Technet. Detta gör man genom att starta setup-programmet för SCCM och välja ”Recover a site”:

SCCMSiteRecoveryWizard

Vad jag hoppades upptäcka var om det i något scenario inte blir en mismatch mellan värdet i databasen och i registret.

Resultat

Så länge SCCM finns installerat på servern finns enbart valet ”Recover the site database…” tillgängligt i wizarden. För att återställa även site servern från en befintlig backup (som måste tas med det inbyggda jobbet i SCCM) så måste man avinstallera SCCM först (alternativt ominstallera Windows).

Jag började med att enbart återställa databasen från wizarden. Jag testade både varianten med att peka ut en backup som jag gjort med det inbyggda SCCM-backupjobbet, och även att manuellt återställa databasen från SQL Management Studio och sen välja Use a site database that has been manually recovered från wizarden.

Resultatet från båda dessa metoder blev exakt detsamma. Återläsningen gick bra, SCCM fungerade fint, mina 1000 importerade objekt var borta, och alla ”rowversion”-värden i databasen ställdes tillbaka till där de var innan de 1000 objekten importerades.

Men, registret återställdes inte och problemet med mismatchen uppstår alltså i det här scenariot – oavsett om man använt SCCMs inbyggda backup eller en vanlig SQL-backup.

Jag gick sen vidare med att börja om med en ominstallerad server, köra setupen igen, och den här gången välja scenariot att återställa hela site servern från backupen.

En liten fotnot här är att jag använde mig av en databas med splittade databasfiler. Detta lyckades setup-programmet inte att återläsa, så wizarden misslyckades. Med en icke splittad databasfil går det dock bra. Jag fick därför först manuellt återställa databasen i SQL Management Studio. Det här problemet måste jag testa mer och återkomma om.

Registernyckeln HKLM\Software\Microsoft\SMS\Components\SMS_Policy_Provicer\MEPHandler finns inte när man gör en ny installation av SCCM, utan skapas första gången man skapar en ny datorvariabel. Jag hade dock förväntat mig att nyckeln skulle finnas från början efter att ha läst tillbaka backupen, men det visade sig att så var inte fallet. Det förvånade mig då man kan se att detta värde tas med i backupjobbet, det återfinns nämligen i filen SMSbkSiteRegSMS.dat som ligger i backupkatalogen. Däremot skapades nyckeln lydigt på nytt när jag lade till en ny datorvariabel, och ”last row version”-värdet pekade korrekt mot det senaste värdet i databasen.

Alltså ingen mismatch mellan registret och databasen i det här scenariot, så datorvariabler kommer fungera som de ska.

Hur registervärdet återskapas vet jag dock inte, det måste finnas någon logik som helt enkelt tittar på det senaste värdet i MEP_MachineExtendedProperties och skriver in detta i registret.

Slutsats och rekommendation

Resultatet blev alltså att genom att enbart återläsa databasen så kommer det alltid bli en mismatch mellan värdet i registret och databasen. Om man återläser hela servern kommer värdet i registret att genereras på nytt och fungera som det ska. Dock skiljer sig inte detta från att göra en ren installation av SCCM och bara återläsa databasen, då registervärdet kommer återskapas även då.

Så vad blir lärdomen och rekommendationen? Om man vill backa tillbaka t.ex. någon ändring man gjort i SCCM, ska vi då enbart läsa tillbaka databasen? Eller ominstallera hela servern? Ska vi använda det inbyggda SCCM-backupjobbet, tillför det något?

Som jag skrev i förra inlägget är förmodligen scenariot som min kund råkat ut för ytterst ovanligt. Det är förmodligen mycket sällan någon läser tillbaka en backup med syfte att radera hundratusentals användarobjekt. Därför kommer mismatch-problemet med datorvariabler knappast vara ett vanligt problem i praktiken.

Detta blir alltså mer ett teoretiskt problem, och min förra slutsats med att detta är ett designfel av Microsoft kvarstår. Värdet borde lagras i databasen där det hör hemma, och inte i registret.

Kan man då känna sig trygg med att enbart läsa tillbaka en databas, utan att ominstallera hela servern? Min åsikt måste bli ”ja” på den frågan. Framför allt om det är en backup från enbart någon dag tillbaka i tiden, och om inga gigantiska förändringar skett. Det finns en rad andra ”rowversion”-värden i registret, så det här teoretiska problemet kan eventuellt uppstå med andra saker. Men det känns alltså osannolikt i de flesta scenarion.

Tillför då det inbyggda SCCM-backupjobbet överhuvudtaget något längre? Svaret måste bli nej från mig, jag ser ingen anledning till att använda det längre. Behöver man återställa hela servern gör man en ren installation och återställer sen databasen, och får på så vis tillbaka allting. De registernycklar som tas i backupen tycks ändå inte läsas tillbaka (vilket verkligen är helknäppt), och i övrigt så tar backupjobbet bara med loggfiler och lite annat som inte känns tillräckligt relevant för att det ska vara värt det.

Rekommendationen blir alltså, fortsätt gör rena databasbackuper och använd dessa för återställning. Databaserna måste som bekant tas om hand om, där backup bara är en del av underhållsjobbet. Favoritmetoden i SCCM-världen är att använda sig av Ola Hallengrens utmärkta lösning för databasunderhåll. Använd denna och ta backuper varje dag. Vill man kan man även ta backup på site servern med det inbyggda backupjobbet eller någon annan metod, men detta blir alltså kaka på kaka som förmodligen aldrig kommer behövas. Dock ska man naturligtvis ha backup på sina source filer, och eventuella andra saker såsom script man har skapat och dylikt.

 

Facebooktwitterredditpinterestlinkedinmail

Guide: Exekvera site maintenance tasks i SCCM 2012 med PowerShell

Då tidigare inlägg som går lite mer på djupet i SCCM har varit populära så tänkte jag slå till med ännu ett i samma tema. Den här gången tänkte jag att vi skulle titta ned lite i databasen igen, och se hur vi letar oss fram till rätt information, och hur vi sedan utför något som inte går att göra direkt i SCCM via PowerShell.

Som exempel kommer jag använda en s.k. ”site maintenance task” i SCCM, och visa hur vi kan starta den manuellt från PowerShell.

DisclaimerFippla aldrig runt i databasen om du inte vet vad du gör eller har bra backuper. Det är inte supportat av Microsoft. Det vi går igenom i den här guiden kan betraktas som säkert, om man inte gör fel, men du gör det på egen risk.

Bakgrund

Om man använder Asset Intelligence i SCCM så tillkommer en hel del möjligheter för inventeringen. Man lägger till nya klasser i WMI, dvs utökar vad som inventeras på klienterna, man kan kategorisera och sammanställa inventerade programvaror på snyggare sätt, och man kan importera in licensinformation om ens applikationer, och på så vis följa upp installerade programvaror kontra faktiska licenser.

När man jobbar med SCCM lär man sig snabbt att saker och ting går långsamt. Allting måste hända i en viss ordning innan ett resultat spottas ut på andra sidan. En del av att vara en uber-administratör för SCCM är att lära sig hur saker och ting hänger ihop under skalet, så att man bl.a. kan trigga igång någonting som man vill ska ske omedelbart. Vilket ju är ett ganska vanligt önskemål. Vem har lust att vänta timmar eller dagar på att en applikation ska installeras, eller en rapport om hur många som installerat den, när chefen står och hänger i dörren och frågar?

Många saker i SCCM bygger på att någonting ska flyttas från en plats till en annan i databasen. Just Asset Intelligence är ett sådant exempel. AI har sina egna tabeller, vyer och stored procedures osv i databasen, och hämtar mycket av sin information från andra tabeller, där inventeringsdata lagras.

Scenario

Vi ska titta lite just på Asset Intelligence. Låt oss säga att vi har installerat en viss programvara på en klient. Vi kör en hardware inventory och ser hur programvaran dyker upp i t.ex. Resource Explorer. Inventeringen har alltså körts, och vi kommer också kunna hitta programvaran i vissa rapporter. Men om vi tittar i vissa Asset Intelligence rapporter så ser vi den däremot inte. Exempelvis om vi har licenser importerade för den här programvaran, och t.ex. tittar på rapporten License 15B – General license reconciliation report by computer. Så varför syns den inte här? Det ska vi ta reda på i den här guiden, och vi ska ta fram en metod för att snabbt uppdatera den här informationen, så att rapporterna börjar funka.

Hur funkar AI?

Lite kort om hur det funkar, och vad som behöver ske i SCCM för att en nyinventerad programvara ska börja dyka upp i AI-rapporterna.

Vi kan enkelt kontrollera vilka programvaror som AI ”känner till” genom att titta under Asset Intelligence och Inventoried Software i SCCM konsolen, under vyn Assets and Compliance. Syns inte programvaran där, så kommer heller inte rapporterna att funka.

Så vad är det för mekanism som ”flyttar” informationen från den vanliga inventeringen till AI? När kan jag förvänta mig att AI har uppdaterats?

En ledtråd till hur man kan tänka här är, att de flesta typer av sådana här aktiviteter, när tabeller i databasen ska uppdateras, sker med s.k. Maintenance Tasks i SCCM. Alla Maintenance Tasks hittar vi genom att högerklicka på Siten i konsolen, under Administration, och välja Site Maintenance.

SummarizeInstalledSoftwareWithPowerShell_1

 

Tittar vi vilka jobb som finns här så hittar vi ett jobb i listan som heter Summarize Installed Software Data. Det låter ju som det vi vill göra, och jag kan avslöja att mycket riktigt är det detta jobb som ansvarar för att uppdatera programvarorna i AI. Om vi tittar på när detta jobb körs så ser vi att standardinställningen är att köra mellan kl. 00-05 varje dag.

Doh! Vi måste alltså vänta till imorgon innan våra AI rapporter är uppdaterade med dagens alla installationer. Och chefen som ville ha svar ASAP…

Microsoft har tyvärr inte gett oss någon ”Run-right-now-I-don’t-want-to-wait-god-damnit”-knapp för att köra dessa maintenance tasks. Det enda sättet vi kan kicka igång dem från GUI’t är att gå in och ändra schemat till ett par minuter fram i tiden. Detta funkar och kan vara ”good enough” som metod någon gång ibland. Men det är inte helt optimalt. Dels måste man komma ihåg att ställa tillbaka schemat igen efter jobbet är klart, och dels funkar det faktiskt inte alltid helt bra om man t.ex. inte ställt in tidsintervallet, alltså fönstret som jobbet får köras under, tillräckligt långt.

Låt oss nu skapa vår egen ”Run-right-now-I-don’t-want-to-wait-god-damnit”-knapp.

Steg för steg…

Vi börjar med att köra jobbet, genom att som jag skrev ovan, ändra schemat inne i konsolen. När jobbet väl körs vill vi ta reda på vad som faktiskt händer i databasen. Det kan vi göra på lite olika sätt. Vi kan köra SQL Profiler och övervaka allt som sker i databasen, och där garanterat få vårt svar. Det är dock inget jag rekommenderar att börja med. Informationen man får kan vara ganska överväldigande, så man kan behöva filtrera och söka ganska länge innan man finner det man letar efter.

Istället tittar vi i SCCMs loggfiler, och den fil vi vill ha heter smsdbmon.log. Här loggas allting som SCCM gör just mot databasen, så låt oss se vad som händer när vi kör Summarize Installed Software Data-jobbet.

SummarizeInstalledSoftwareWithPowerShell_2

 

Lämpligtvis använder vi av oss t.ex. Highlight-funktionen i CMTrace och markerar orden ”Summarize Installed Software Data”. Vad vi ser ovan är att jobbet har körts och i det här fallet lagt till 0 rader i en tabell som heter INSTALLED_SOFTWARE_DATA_Summary.

Det var den första ledtråden, bra. Nu vet vi var datat lagras. Men vad använde SCCM för metod för att uppdatera denna tabell? Det ser vi tyvärr inte i loggen. Men SCCM använder sig av Stored Procedures i SQL för den här typen av uppgifter, så allt vi behöver göra är att leta upp rätt SP. Hmm, finns några hundra, så var börjar vi?

In i SQL Management Studio.
Vi vet ju nu vad tabellen heter, så låt oss titta på den. Vi kan ju börja med att högklicka på den och välja Select top 1000 rows så ser vi innehållet. Det vi ser här är en lista med exakt samma programvarutitlar som vi ser i SCCM-konsolen under Inventoried Software. Det verkar ju lovande, men vi vet fortfarande inte hur tabellen uppdateras. Vi högerklickar därför på tabellen och väljer View Dependencies.

SummarizeInstalledSoftwareWithPowerShell_3

 

Aha, det finns en stored procedure som heter spLoadInstalledSoftwareDataSummary. Låt oss undersöka den, genom att leta upp den i den lååånga listan med stored procedures, högerklicka på den och välja Modify.

När vi tittar närmare på koden ser vi att vad denna SP gör lite kortfattat är att ta en del information från tabellen INSTALLED_SOFTWARE_DATA, lagra resultatet i en temporär tabell och sedan jämföra med innehållet i INSTALLED_SOFTWARE_DATA_Summary. Programvarutitlar som lags till eller tagits bort kommer att uppdateras i INSTALLED_SOFTWARE_DATA_Summary.

Om vi tittar i INSTALLED_SOFTWARE_DATA så ser vi här samtliga inventerade programvaror från alla datorer. Med andra ord är INSTALLED_SOFTWARE_DATA_Summary en summering av INSTALLED_SOFTWARE_DATA (duh! därav tabellens namn) där ett hashvärde används för att identifiera varje unik programvara.

Jaha, det verkar ju logiskt hur det hänger ihop. Vi testar väl att köra denna stored procedure då, högerklicka och välj Execute Stored Procedure.

Tada! Om vi tittar i tabellen INSTALLED_SOFTWARE_DATA_Summary igen så har mycket riktigt vår saknade programvara dykt upp där. Var det verkligen så enkelt? Låt oss titta i SCCM-konsolen också för säkerhets skull. Jajamen, under Inventoried Software har applikationen dykt upp. Strålande.

Var det någon som sa PowerShell?

Nu hade ju jag lovat att vi skulle göra detta med PowerShell också. Vem vill hålla på och hoppa in i SQL Management Studio hela tiden för att göra sådana här saker? Det är ju PowerShell vi vill använda för allt. Så kan man köra en stored procedure i SQL med PowerShell? Jajamen. Vi kan göra det på lite olika sätt, men jag tänker nöja mig med att visa det enklaste sättet här.

Vi använder oss av cmdleten Invoke-Sqlcmd från modulen SQLPS som medföljer när man installerar SQL.

Svårare än det lilla simpla exemplet ovan är det inte. Byt ut CM_S01 mot namnet på din databas (alltså din sitekod), och spara scriptet som t.ex. Update-InventoriedSoftware.ps1 så kan du när som helst köra det.

Slutsats

Genom att ta sig tid att titta lite ”under skalet” kan man lära sig mycket. Och kunskap är nyckeln till hur vi förenklar vårt arbete, vår vardag och våra liv. Den här lilla guiden hade som syfte att hjälpa till att utveckla ett tankesätt, hur man börjar leta efter information i SCCM och hur man tar sig framåt och finner det man söker.

Det här exemplet är också förhoppningsvis till faktisk nytta för någon, i alla fall för er som använder sig flitigt av AI.

Hur skulle man kunna bygga vidare på det här och förfina lösningen?

Genom att använda samma metodik kan vi leta fram hur andra site maintenance tasks fungerar, och t.ex. låta namnet på stored proceduren vara en parameter till vårt script. På så vis kan vi enkelt starta igång olika maintenance tasks. Skulle man kunna lägga till detta i SCCM-konsolen så att man bara behöver klicka någonstans och få upp en lista på våra maintenance tasks, och då kunna köra igång dem direkt? Jajamen, visst kan vi göra det.

Det är, som alltid, bara vår fantasi som sätter gränserna.

 

Facebooktwitterredditpinterestlinkedinmail

SCCM 2012: Datorvariabler fungerar inte efter en återställning från backup

Uppdatering 2015-09-19: En uppföljning till detta inlägg med en vidare analys av problemet, finns nu här.

Jag har just spenderat hela dagen med att felsöka ett problem av den lite ovanligare sorten, och tänkte här återge i stora drag hur jag gick tillväga och vad jag hittade under det arbetet. Är man intresserad av felsökningsmetodik på lite djupare nivåer i SCCM 2012, där man tack och lov rätt sällan behöver pilla runt (och absolut inte SKA pilla runt om man inte är väldigt säker på vad man gör), så kan detta inlägg vara intressant att läsa. Men framför allt är också slutsatsen och upptäckten av den faktiska felorsaken intressant att känna till för alla. Jag lärde mig själv en del nytt som jag tar med mig i bagaget för framtiden.

Bakgrund

Under förra året gjorde jag en nyinstallation av SCCM 2012 hos en kund, som sedan under 2015 fortsatt införandet i delar av sin organisation. I somras råkade av misstag en ”AD user discovery” ske mot en mot en plats i AD som innehåller användarkonton som inte ska hanteras i SCCM. Det var ingen liten mängd utan rörde sig om flera hundratusentals konton. Teoretiskt är detta inget problem i sig då det ”bara” är att radera dessa konton i SCCM. Men då det rör sig om sådana här mängder, i en miljö som heller inte är dimensionerad för detta, så upptäcker man hur lång tid det faktiskt tar att radera ett objekt i SCCM. Det skulle helt enkelt ta alldeles för lång tid att rensa all denna information, så det beslutades istället att en återläsning av backupen skulle ske.

Databasbackuper kördes varje natt och man hade inga förändringar som skulle gå förlorade, så tanken var att detta skulle gå oändligt mycket snabbare än att försöka rensa ur databasen.

Sagt och gjort, databasen lästes tillbaka och vips var man av med över 300 000 konton som man inte ville ha på en bråkdel av tiden jämfört med att radera allting. Här ska noteras att enbart databasen lästes tillbaka, en ”site recovery” kördes inte. Enligt dokumentationen ska egentligen alltid en site recovery köras, men det är egentligen oklart varför och dokumenationen är egentligen ganska luddig. I SCCM 2012 finns t.ex. inte längre någon ”site control fil” och det är numera supportat att göra en site recovery med enbart en databasbackup från t.ex. ett SQL Maintenance Job. All relevant information och konfiguration ska finnas i databasen, så att återställa just bara databasen kan man ju tycka räcker. Vad gör ”site recovery”-processen i övrigt för magi som gör att man bör köra den? Det framgår inte i någon dokumentation, och här skulle jag säga råder en viss förvirring i världen.

Hur som helst, här återläste man alltså enbart databasen. Allting verkade frid och fröjd, allt ”lyste grönt” och fungerade som det skulle. Tills man började köra ”OS deployment” och rulla burkar.

Själva installationerna gick precis som vanligt utan problem, men man använder också variabler på både collections och på datorobjekten för att dynamiskt kontrollera en rad olika saker i installationen. Vad man nu upptäckte var att datorvariablerna inte längre fungerade, och ignorerades helt och hållet av task sequencen.

Analys

För att felsöka problemet fick jag först börja ”från början”, då jag själv inte varit med vid återläsningen från backup och inte sett miljön på länge. Jag började alltså med en enkel hälsokontroll för att se om det fanns några allmänna fel eller problem, eller tecken på att något gått fel vid återläsningen. Allting tycktes dock vara ett praktexempel på en fungerande miljö utan några konstigheter.

Då just problem med datorvariabler och OSD har varit en känd bugg tidigare så kontrollerade jag också snabbt att den hotfixen inte längre var applicerbar (den byter bara ut en liten dll-fil), och så var inte fallet. Det hade också varit konstigt då versionsnivån var R2 SP1 (dock utan CU1), där denna fix för länge sen ingår. Service packen hade också installerats efter återläsningen från backup, vilket annars är en bra metod för att lösa många problem då i princip de flesta delar på hela site servern ominstalleras och återställs. Men problemet kvarstod alltså.

Jag fortsatte sedan med att skruva upp loggningen till maxnivå på SMSTS.log på klienten (en bra artikel för hur man gör detta och ändrar maxstorleken på loggen, kan man läsa här). I loggen kunde jag mycket riktigt utläsa ”Found 0 machine variables” och att någon policy för datorvariabler aldrig ens försökte laddas ned. Däremot fungerade collection variabler utan problem. Något annat intressant fanns inte här, men detta räckte för att visa att det helt enkelt inte fanns någon policy för datorvariabler att hämta på management pointen. Det kändes alltså tydligt som ett serverproblem och inte ett klientproblem.

Jag aktiverade därefter debug logging på management pointen och började gå igenom de olika MP-loggarna, och matcha vad som hände där samtidigt som klienten efterfrågade sin policy. Kort sagt fanns inget intressant att hitta om problemet i dessa loggar. Jag såg inga tecken på problem i management pointen, och kunde helt enkelt inte se några spår av en policy med datorvariabler hämtats från databasen.

Nästa steg i kedjan blev alltså att börja undersöka själva databasen, och den process som genererar policies som sedan levereras till MPn. Den komponent i SCCM som ansvarar för detta heter SMS_POLICY_PROVIDER och har en loggfil som heter policypv.log. Jag började alltså gräva i denna loggfil, samt även i loggen smsdbmon.log för att se vad hände i databasen.

Jag började skapa variabler på datorobjekt, både i den riktiga miljön samt i min egen testmiljö, där allting fungerade som det ska, och jämförde resultaten.

Så fort en variabel skapas kan följande utläsas i smsdbmon.log:

SCCM_Datorvariabler_1

Ok, så tabellen MEP_MachineExtendedProperties har uppdaterats. Detta är också vad som är förväntat, och detta skedde utan problem, likadant i både problem-miljön och min testmiljö.

Det som ska ske härnäst är att en ny policy ska genereras för datorn som har fått variabeln, och denna policy ska alltså innehålla variabeln och dess värde. Detta ser man tydligt i policypv.log, och så här ser det ut i min testmiljö när det fungerar som det ska:

SCCM_Datorvariabler_2

Det vi ser här är ett urval ur loggen som visar hur en ny policy som innehåller ”machine extended properties”, vilket är lika med datorvariabler, har genererats för en dator med ett visst ”machine ID” och GUID. En snabb koll i konsolen, alternativt ”Get-CMDevice -Name MinTestDator” visar att detta ID och GUID mycket riktigt hör till den dator där jag skapade variabeln.

I problem-miljön såg det dock lite annorlunda ut. Samma saker sker fram till raden i loggen som börjar med ”MEP-Querying MV for rowversion...” men där det sedan ska returneras en ny policy, så var det här helt tomt. Ingen policy med ”machine extended properties” kom tillbaka, och SMS_POLICY_PROVIDER fortsatte glatt att generera policy för allt annat (applikationsinstallationer, device settings, osv).

Loggraden ”MEP-Querying MV for rowversion...” ser i sin helhet ut så här:

Det körs alltså en query i databasen, och därefter ska policyn som innehåller variabeln returneras. Hmm, kunde det vara så att denna query inte gav önskat resultat? Det var dags att på allvar titta ned i databasen.

Först lite bakgrund till hur det SKA se ut i databasen när allting fungerar som det ska.

När man skapar en variabel på en dator så uppdateras följande tre tabeller i databasen:
MEP_MachineVariables
MEP_MachineExtendedProperties
MEP_MachinePolicies

Jag testade att skapa variabeln ”MinTestVariabel” på min testmaskin ”testar3” som har Machine ID 16777235, och tittar i den första tabellen.

SCCM_Datorvariabler_3

Vi kan tydligt se att variabeln har skapats (värdet är dock ”scramblat” och går inte att läsa i klartext).

Nästa tabell, MEP_MachineExtendedProperties, innehåller ingen information i sig, utan är bara en plats för att hålla reda på vilka datorobjekt som faktiskt har variabler definierade, och när en förändring av dessa görs.

SCCM_Datorvariabler_4

Återigen hittar vi en rad med min testdator, information om när ändringen gjordes, samt någonting som heter rowversion. Vi återkommer till detta.

När väl dessa båda tabeller är uppdaterade ska, om allt fungerar korrekt, en ny policy genereras för datorn som innehåller variabeln. Att så har skett ser vi i den sista tabellen.

SCCM_Datorvariabler_5

Min testdator har dykt upp här, och i det här läget kan man alltså se i policypv.log att en ”MEP-policy” för datorn mycket riktigt hämtas.

I problem-miljön dök dock datorn bara upp i de två första tabellerna, men aldrig i den tredje. Ok, så variabeln lagras korrekt i databasen, och även den tidsstämplade informationen om att det faktiskt finns en variabel (i MEP_MachineExtendedProperties), men någon policy skapas tydligen aldrig. Det var dags att gå till botten med hur logiken i mekanismen som genererar denna policy faktiskt fungerar. Det var dags att göra en databas ”trace”.

För detta ändamål använder vi verktyget SQL Server Profiler vilket är ungefär motsvarigheten till Process Monitor i databasvärlden. Vi kan följa i realtid exakt vad som sker i databasen, vilka queries som görs, vilka transaktioner som sker. Precis som med Process Monitor blir det snabbt ett hav med information, och särskilt då det gäller en produktionsmiljö där det hela tiden sker saker. Det gäller alltså att veta ungefär vad man letar efter.

För att minska mängden information skapade jag ett filter: ApplicationName Like SMS_POLICY_PROVIDER
Detta då jag ju visste att det är denna komponent som genererar policies och att problemet därför måste ligga där, så med detta filter blev mängden hanterbar.

Genom att söka på ”MEP” fick jag ganska snabbt fram en hel del intressant information. Jag kunde se att det första som skedde var att följande query gjordes:

Aha, detta var ju samma query vi såg tidigare i policypv.log. Och mycket riktigt, efter denna query kunde jag i tracen se i min testmiljö steg för steg hur policyn skapades, men i problem-miljön hände ingenting. Så låt oss undersöka denna query.

Det den gör är kort och gott att leta fram alla datorer där en variabel har lagts till, tagits bort eller förändrats. Och denna information sparades ju i tabellen MEP_MachineExtendedProperties. Kör jag denna query manuellt så får jag mycket riktigt till svar just den dator där jag just skapat en variabel (i det här fallet min testdator ”testar3”).

Så logiken här är alltså att leta fram enbart de datorer där en förändring av en variabel har skett genom att titta i MEP_MachineExtendedProperties, därefter generera en policy för denna dator och spara information om detta i MEP_MachinePolicies.

I problem-miljön såg det ut så här:

SCCM_Datorvariabler_6

Alltså samma query här, men i den här miljön returneras inget svar vilket jag snabbt kan kontrollera genom att köra den manuellt. Så vad är problemet, varför hittas inte min dator där jag lagt till en variabel? Jag kunde ju se att min dator låg i tabellen MEP_MachineExtendedProperties precis som den ska, och det är ju där queryn ställer sin fråga. Låt oss återigen titta närmare på queryn. Den filtrerar resultatet genom att ställa villkoret att innehållet i kolumnen rowversion måste vara större än ett visst värde, som anges i hexadecimal form. Jag jämförde värdet i queryn med det högsta värdet som faktiskt fanns i tabellen, och upptäckte att värdet i queryn var över 4 miljoner högre än vad som fanns i tabellen. Så kort sagt, den frågar efter någonting som är otroligt mycket högre än vad som faktiskt finns, och får därför tillbaka ett tomt svar. Policy providern kommer tolka detta som att ingen dator har uppdaterat någon variabel och någon policy kommer därför heller inte att genereras. Logiskt, och nu börjar vi närma oss lösningen.

Så vad är då detta ”rowversion” och varför är värdet i queryn fel?

Enkelt förklarat används ”rowversion” för att spåra förändringar som sker i en databas, som en sorts versionshantering i tabellerna. Värdet är globalt för hela databasen men är frivilligt att använda i varje enskild tabell. Så fort en tabell innehåller en ”rowversion-kolumn” kommer den globala räknaren att öka med ett steg så fort en förändring sker i denna tabell. Mer detaljer finns att läsa på MSDN.

Nu är sista pusselbiten på plats för att förstå hur logiken fungerar med queryn ovan. Rowversion används alltså i tabellen MEP_MachineExtendedProperties för att hålla koll på varje gång en variabel läggs till, uppdateras eller tas bort. När så sker ska en ny policy genereras. Policy providern håller koll på senaste värdet för rowversion, och behöver därför bara ställa en fråga efter alla datorer som har ett högre värde för att på så vis få reda på vilka datorer som ska ha en ny policy.

Men varför trodde policy providern att det senaste rowversion-värdet var hela 4 miljoner högre än vad det verkliga värdet faktiskt var i databasen?

Hela problemet hade ju börjat efter en backup-återläsning av en SCCM-databas som innehöll ~300 000 färre objekt. När importen av alla dessa objekt skedde så motsvarade det tydligen ca 4 miljoner transaktioner i databasen, varpå rowversion ökades upp motsvarande. Efter återläsningen så återställdes detta värde till samma som det var innan hela importen, alltså ca 4 miljoner lägre.

Det var nu uppenbart att SCCM sparar detta värde även någonstans UTANFÖR databasen, och att vi därför fick detta glapp mellan vad policy providern trodde var den senaste förändringen, och vad som faktiskt stod i databasen. Så var kan detta tänka lagras?

Registret känns ju som en väldigt kvalificerad gissning, och nu råkade jag veta att de flesta SCCM-komponenter har en egen registernyckel under HKLM\Software\Microsoft\SMS\Components, och mycket riktigt så finns en nyckel där även för policy providern. Jag började med att titta där och fick jackpot direkt:

SCCM_Datorvariabler_7

VOILA! Här står klart och tydligt nyckeln MEPHandler som har ett värde med namn ”Last Row Version”. Kan det vara så enkelt? Jag jämförde datat i det värdet, ett hexadecimalt tal, med värdet för rowversion i den query som jag tidigare sett i policypv.log och i SQL tracen, och det var såklart exakt samma värde. Här var alltså det gäckande talet som var 4 miljoner för högt och som gjorde att inga datorvariabel-förändringar fångades upp i databasen.

Lösningen? En snabb titt igen i MEP_MachineExtendedProperties och sortera efter just rowversion för att leta upp det högsta värdet i tabellen:

Jag kopierade detta värde och klistrade in i registret och PANG så började allting att fungera perfekt igen.

Slutsats

Förutom att den här typen av felsökningsarbete är fantastiskt roligt, sådär som bara de nördigaste av de nördiga kan uppskatta, så lämnar dagens övningar ett par nya lärdomar och även ett frågetecken efter sig. Traditionellt har det i SCCM-världen alltid, fram till härom året, varit ett ”big no-no” att göra en återläsning på något annat sätt än från en backup gjord med det inbyggda backup-jobbet i SCCM. Det har alltså inte räckt att bara peka på en backup av databasen. Själv har jag haft lite svårt att vänja mig vid tanken på att man numera kan göra så.

Det inbyggda backupjobbet tar, förutom databasen, även med inboxarna och andra saker från filsystemet, samt även alla registernycklar. Och faktum är, jag dubbelkollade i min testmiljö nu ikväll, att just denna nyckel som innehåller ”last row version” tas med i den backupen. Så med andra ord, hade man använt den traditionella SCCM-backupen hade detta problem aldrig uppstått. Men när man återställer från en sådan backup så gör man å andra sidan också per definition en site recovery.

Men frågetecknet är detta: hade en site recovery fixat till problemet som här uppstod, och på något sätt synkat värdet i registret med databasen?

Jag vet inte, det får hamna på min att-göra-lista att prova i min testmiljö. Jag hoppas att så är fallet. Om inte, så är detta en brist i det fullt supportade scenariot att göra en återställning med enbart en databasbackup.

Det här är första gången jag ser en miljö läsas tillbaka på det här sättet, alltså att man bara lagt tillbaka databasen men struntat i site recovery. Men jag tror att det inte är helt ovanligt att så sker. På olika bloggar och forum runt om i världen nämns det ofta att backup i SCCM numera enbart handlar om databasen, och att det är den bästa metoden för då kan man använda ett SQL maintenance job eller DPM eller liknande, och därmed komprimera backupen och spara utrymme, och att allting är snabbare och bättre osv. Med andra ord börjar folk gå ifrån att använda det inbyggda backupjobbet i SCCM. Och jag kan tänka mig att många också gör en återläsning med just bara databasen. För allting finns ju där, och det funkar ju faktiskt. Dvs, förutom det problem som uppstod just i det här fallet. 🙂

Nu ska sägas att det är mycket osannolikt att det här scenariot uppstår, det här var förmodligen ett ganska unikt fall. Att man i en produktionsmiljö väljer att läsa tillbaka en backup som innehåller över 300 000 färre objekt hör knappast till det vanliga. Är det bara en liten differens mellan policy providerns räknare i registret och värdet i databasen, så äts den skillnaden upp ganska snabbt med alla transaktioner som sker hela tiden i databasen.

Kan det finnas andra saker som inte funkar när man återställer enbart databasen utan att också göra en site recovery? Säkert. Slutsatsen måste därför bli att verkligen följa site recovery wizarden i alla lägen.

En sista fundering från mig. VARFÖR i herrans namn sparas detta värde i registret, och inte i databasen? Varför får helt enkelt inte policy providern istället en egen liten tabell där den kan skriva detta och underhålla detta värde? Detta är i min mening ett designfel från utvecklarna. Jag kan i alla fall inte föreställa mig något bra skäl till att lagra en databaspekare utanför databasen.

 

Facebooktwitterredditpinterestlinkedinmail

BSOD i Windows 7 pga registerkomprimering i WinPE 5.0

Precis innan sommaren råkade jag ut för ett Blue-Screen-of-Death-problem hos en kund. Jag hade skapat en ny Windows 7 32-bit image med alla senaste uppdateringar fram t.o.m. juni. Det här är en image som uppdateras regelbundet, och några andra förändringar hade inte skett i imagen vid det här tillfället. Jag misstänkte alltså att problemet berodde på någon av juni månads Windows-uppdateringar.

Jag analyserade blåskärmen och såg att felet som rapporterades var: 0xF4_36b1_IMAGE_wininit.exe

Av en slump kände jag igen just detta fel, då jag sett det rapporteras från flera olika håll under 2015. Varför jag råkade ut för det just i juni och inte tidigare är märkligt, men felet är känt sedan tidigare och uppträder lite slumpmässigt. Man råkar typiskt sett bara ut för det om man kör en 32-bitars boot-image, vilket jag gjorde i det här fallet, och det uppstår bara i WinPE 5.0 och senare. En noggrannare förklaring till problemet beskrivs här:

http://blogs.technet.com/b/dip/archive/2015/01/21/win2008r2-win7-stop-0xf4-during-task-sequence-os-deployment.aspx

Kort sagt är lösningen följande:

  1. Mounta boot-imagen:
    dism.exe /mount-wim /wimfile:<path-to-wimfile> /index:1 /mountdir:C:\Mount
  2. Öppna regedit, välj Load hive och öppna filen C:\Mount\Windows\System32\config\SOFTWARE
  3. Lägg till följande registervärde:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet001\Control\Session Manager\Configuration Manager

    Name: RegistryReorganizationLimitDays
    Datatype: DWORD
    Value: 365

    (ja det ska vara CurrentControlSet001 ovan, detta omvandlas sen till CurrentControlSet när WinPE körs)

  4. Välj Unload hive och stäng regedit.
  5. Avmontera imagen:
    dism.exe /unmount-wim /mountdir:C:\Mount /commit

 

Facebooktwitterredditpinterestlinkedinmail

SCCM 2012 R2 CU5 finns nu tillgänglig

Igår släpptes Cumulative Update 5 till SCCM 2012 R2.

Läs mer och hämta hem uppdateringen här: https://support.microsoft.com/en-us/kb/3054451

Notera att några uppdateringar för PowerShell inte längre ingår i cumulative updates. Alla PowerShell cmdlets har istället flyttats ut till System Center Configuration Manager Cmdlet Library som är en separat installation. Har ni inte redan installerat den, så gör det nu.

Nästa vecka ska det också släppas nya service packar till SCCM 2012.

 

Facebooktwitterredditpinterestlinkedinmail