By Andreas Nick on Mittwoch, 11. Januar 2017
Category: App-V

Automatische Sequenzierung von App-V Anwendungen

Microsoft bietet mit der Windows PowerShell auf dem Sequencer eine Möglichkeit, die Paketerstellung zu automatisieren. Die Nutzung dieser Module ist einfach. Bei dem Sequencer ist wiederum zu beachten, dass dieser für die genutzte Umgebung Best Practice zu installieren ist. In der Regel wird man die automa-tische Paketierung von außen steuern, also einen Sequencer in einer Hyper-V- oder VMware-Umgebung nutzen und diesen vor jeder Aktion automatisch wieder zurücksetzen.

Import der Sequencer PowerShell-Erweiterung:

Import-Module AppvSequencer

Mit dem Befehl Expand-AppvSequencerPackage kann ein App-V Paket über einen PowerShell-Befehl expandiert werden. Das verhält sich gleich wie bei einer Installation. Denkbar ist eine Automatisierung, die Pakete öffnet, eine Datei austauscht und anschließend wieder mit dem Sequencer packt.

Expand-AppvSequencerPackage [-AppvPackagePath]  [ ]

Der Befehl NewAppvSequencerPackage ist der PowerShell-Aufruf zur Erstellung einer neuen Sequenz. Das eigentliche Paket kann beispielsweise über ein Skript installiert werden. Als weiterer Parameter ist es möglich, ein PVAD anzugeben und auch ein Template, welches automatisch Verzeichnisse von der Se-quenzierung ausschließt. Ein Package Accelerator ist hingegen kaum noch gebräuchlich.

New-AppvSequencerPackage [-Name]  [-Path]  [-Installer]  [[-PrimaryVirtualApplicationDirectory]  ] [-FullLoad] [-TemplateFilePath  ] [ ]

Parameter Set: ByPackageAcceleratorInstalledFiles

New-AppvSequencerPackage [-Name]  [-Path]  [-AcceleratorFilePath]  [-InstalledFilesPath]  [ ]

Parameter Set: ByPackageAcceleratorInstallMedia

New-AppvSequencerPackage [-Name]  [-Path]  [-AcceleratorFilePath]  [-InstallMediaPath]  [ ]

Die Paketerstellung kann beispielsweise so erfolgen:

New-AppvSequencerPackage -Name "MeinPaket" -TemplateFilePath "C:\MeinTemplate.appvt" -OutputPath "C:\MeinePakete" -Installer "C:\Installers\MyApp\setup.exe"

Die Anweisung Update-AppvSequencerPackage ist dafür gedacht, automatisch ein Skript oder eine Hotfix-Installation über ein vorhandenes Paket zu installieren. Als Angabe wird das Quellpaket und über -Installer ein Setup oder ein Skript übergeben.

Update-AppvSequencerPackage [-InputPackagePath]  [-Name]  [-Path]  [-Installer]  [-FullLoad] [ ]

Automatische Paketierung mit PowerShell in der Praxis

Für die automatisierte Paketierung hat man mehrere Probleme zu lösen. Zum einen ist es meist ein kom-plexer Ablauf, der auf einem Zielsystem durchzuführen ist, zum anderen soll der Vorgang möglichst sau-ber und störungsfrei ablaufen. In diesem Kapitel wird eine Möglichkeit gezeigt, wie man MSI-Pakete au-tomatisch nach App-V paketieren kann. Der Nachteil ist dabei leider auch, dass kaum eine Konfiguration der Pakete möglich ist. MSI-Pakete können in der Regel mit einem „/q“ Parameter silent (still) installiert werden. Zusätzlich empfiehlt sich der Parameter „/norestart“, um den Sequenzierungsprozess nicht ab-brechen zu lassen. In der folgenden Abbildung ist der Ablauf in etwa dargestellt. 

Das Besondere an dieser Lösung hier ist, dass diese fast beliebig ausgebaut werden kann. Denkbar ist ein automatischer Start der Anwendung, um einen Feature-Block 1 zu erhalten. Es gibt kommerzielle Herstel-ler, die zwar bequemere Lösungen zur automatischen Paketierung bieten, die lassen sich einen solchen Vorgang aber teuer per Paket bezahlen. Das hier angesprochene Verfahren ist kostenlos und zum Preis eines Buchs zu haben. Diese Automatisierung setzt eine VMware-Umgebung voraus. Das Ganze auf Hy-per-V zu ändern, sollte aber auch kein Problem sein.


Ablauf einer automatischen Paketierung mit Microsoft App-V


Basis ist die VMware PowerCLI. Eine zu diesem Zeitpunkt aktuelle Version kann hier gefunden werden:

https://www.vmware.com/support/developer/PowerCLI/

Die folgenden Abläufe können ganz ähnlich auch mit Hyper-V abgebildet werden. Beispielsweise für eine Automatisierung, um mit dem AppBot Citrix Application Streaming Pakete nach App-V zu konvertieren. Um die Vorgehensweise zu verdeutlichen, wird auf jegliche Fehlerverarbeitung verzichtet. Also so nur in einer Testumgebung nutzen.

Ablauf der Paketierung mit einem VMware VirtualCenter:

Anmeldevorgang am VirtualCenter über einen SecureString. Der kann durchaus auch auf der Festplatte gespeichert werden . Zuvor müssen allerdings die notwendigen Komponenten der VMware PowerCLI importiert werden.

Add-PSSnapin VMware.VimAutomation.Core
Import-Module VMware.VimAutomation.Vds

$RootDirectory = $PSScriptRoot.ToString()

#Secure key for encription

[byte[]] $key = (1,2,3,4,5,6,7,8,9,1,2,3,4,5,1,1)

$vcenterUser = "administrator @ vsphere.local";
$vcenterServer = “MYVCENTERSERVER” #Or IP address$vc.

if(-not (test-Path $($RootDirectory + "\vcenterpass.txt") )){
$SecurePass = read-host -AsSecureString "Password for VMware vSphere:" | ConvertFrom-SecureString -Key $key | Out-file $($RootDirectory+"\vcenterpass.txt")
}


$SecurePass = Get-Content ($RootDirectory + "\vcenterpass.txt") | ConvertTo-SecureString -Key $key
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $vcenterUser, $SecurePass

Anmeldung am VMware VirtualCenter Server

#Connect VCenter
$vc = Connect-VIServer -Server $vcenterServer -Credential $credentials -Verbose

Wir wollen PowerShell Remoting die Übertragung der Pakete nutzen. PowerShell Remoting ist ei-ne Schnittstelle, die die Ausführung von Befehlen auf einem anderen Computer erlaubt. Leider kann der eigentliche Sequenzierungsprozess nicht mit PowerShell Remoting erfolgen. Bei einer Sequenzierung kommt es zu Fehlern. Aus diesem Grund nutzen wir zusätzlich das Tool PSExec aus Sysinternals. PowerShell Remoting funktioniert nach der Aktivierung in einer Domäne mit dem Befehl:

Enable-PSRemoting -Force

Wenn sich der Client, beispielsweise der Sequencer, nicht in einer Domäne befindet, und das ist eher üblich, muss dem steuernden System erlaubt werden, auf der Gegenstelle (dem Sequencer) PowerShell Remoting zu nutzen. Wir erlauben also nicht auf dem zu steuernden Gerät, dass ande-re Systeme darauf zugreifen dürfen, sondern wir erlauben das auf dem Gerät, welches den Vor-gang steuert.

Für die folgende Anweisung ist es möglich, eine kommaseparierte Liste mit IP-Adressen und Namen anzugeben. Das Sternchen ist eine Wildcard für alle Systeme.

Set-Item wsman:\localhost\client\trustedhosts *
-it

Die Verbindung kann anschließend mit dem Befehl Test-WsMan ge-prüft werden. Ein Remotebefehl kann wie folgt aussehen:

Invoke-Command -ComputerName COMPUTERNAME -ScriptBlock { MeinBefehl } -credential $credentials

Die Anmeldedaten für den Sequencer werden wie die Daten für das Virtual Center über einen Secure String eingelesen und können auch auf der Festplatte ausgelagert werden. Der Benutzer muss über administrative Rechte auf dem Sequencer verfügen.

#Connection settings Sequencer
$vmuser='administrator' # Admin user on the virtuellen maschine use domain\administrator for a domain member
$sequencer = “seq2012r2en” #DNS name or IP address

if(-not (test-Path $($RootDirectory + "\vmpwasswordfile.txt") )){
read-host -AsSecureString "Please enter the Password for the sequencer:" | ConvertFrom-SecureString -Key $key | Out-file $($RootDirectory + "\vmpwasswordfile.txt")
}

Wir nehmen an, dass alle zu paketierenden MSI-Dateien in einem Verzeichnis mit diesem Skript liegen. Beispielsweise „MSI-Files“. Diese MSI-Dateien können dem Befehl New-AppvSequencerPackage paketiert werden. Jedoch kann es sein, dass komplexere Dinge erledigt werden sollen. Daher soll die eigentliche Paketierung über eine CMD-Datei erfolgen. In der könn-ten auch komplexere Abläufe ausgeführt werden.

Wir müssen alle MSI-Dateien in dem Verzeichnis finden und automatisch durch den Sequencer paketieren lassen. Als Vorbereitung nehmen wir einen Sequencer ohne Domänenintegration. Für diesen muss ein Snapshot im laufenden Betrieb erstellt werden. Der Snapshot in diesem Beispiel bekommt den Namen „NeutralOn“. Der Aufruf des Sequencers über PowerShell Remoting be-reitet Probleme. Leider funktioniert mit dem PS-Remotaufruf nicht immer alles. Diese Probleme lassen sich durch den Einsatz des Befehls PSExec aus den Sysinternals lösen. Zunächst die Schleife



Eine Schleife durchsucht nun das Verzeichnis MSI-Files, welches im gleichen Ordner wie dieses Skript liegen muss.

foreach ($msifile in Get-ChildItem "$RootDirectory\MSI-Files"){

Write-Host $("Create appv file from the MSI " + $msifile.name) `
-ForegroundColor Yellow

Vor jeder Paketerstellung muss der Snapshot auf einen neutralen Zustand gesetzt werden. Weiter-hin wird auf die VMware-Tools gewartet (die müssen auf dem Sequencer installiert sein). Damit kann erkannt werden, ob unser Sequencer vollständig zurückgesetzt wurde.

#reset Snapshot
$vm=Get-vm -Server $vcenterServer -Name $sequencer
Write-host "Set snapshot $SnapshotName on $sequencer"
Set-VM -VM $vm -Snapshot $SnapshotName -Confirm:$false | Wait-Tools


Das MSI muss auf den Sequencer kopiert werden.


Abbildung : MSI-Pakete im Paketverzeichnis

#Copy MSI
Copy-Item $msifile.FullName -destination `
$('\\' + $sequencer +'\c$\')

Die Vorbereitungen zur Sequenzierung erledigt die eine PowerShell Remoting Funktion. In dieser werden alle Vorbereitungen getroffen, um die eigentliche Sequenzierung zu starten. In $appvname wird ein Name für die Sequenz generiert, der nur aus alphanumerischen Zeichen besteht.

#Create sequence name
$appvname = $(($msifile.name).Replace('.msi',''))
$appvname = $appvname -replace "[^a-zA-Z]",""

#Start Sequencing
Invoke-Command -ComputerName $sequencer -Authentication Default `
-Credential $vmcredentials -ScriptBlock {
param([String] $MSIName,
[String] $appvName
)

Es wird unter c:\Sequence.cmd eine Batch-Datei erstellt, die die den Ablauf zur Paketerstellung enthält.

#Create Installation batch
"msiexec /q /norestart /i c:\$MSIName" | Set-Content -Encoding Ascii -Force C:\sequence.cmd

'timeout 3' | Add-Content -Encoding Ascii c:\sequence.cmd

Ein Verzeichnis für die Paketausgabe auf dem Sequencer wird erzeugt

new-item "c:\sequence\" -Force -ItemType directory | out-null

Nun wird ein PowerShell-Skript erstellt, welches die eigentliche Sequenzierung durchführt. Mit ausreichender Berechtigung könnte an dieser Stelle auch schon direkt der Sequenzierungsbefehl gestartet werden.

"Import-Module Appvsequencer" | Set-Content -Encoding Ascii -Force `
C:\CreateSequence.ps1

"New-AppvSequencerPackage -Installer c:\sequence.cmd -Name $appvName -OutputPath c:\sequence\ -ErrorAction SilentlyContinue" | Add-Content -Encoding Ascii C:\CreateSequence.ps1

#Create Sequence
#New-AppvSequencerPackage -Installer c:\sequence.cmd -Name $appvname -OutputPath "c:\sequence\" -ErrorAction SilentlyContinue

Der Invoke-Befehl kann geschlossen werden. Als Argumente werden der Name des MSI und der Name für das App-V Paket übergeben.

} -ArgumentList $msifile.name, $appvname

Den eigentlichen Aufruf zur Remotepaketierung soll in diesem Fall das Sysinternals Tool PSExec übernehmen:

https://technet.microsoft.com/de-de/sysinternals/pxexec.aspx

Ein Vorteil von PSExec ist, dass die Berechtigungen bei der Sequenzierung keine Rolle mehr spielen. Ein Nachteil ist leider die komplexe Handhabung des Tools. Unter anderem muss das Kennwort des Sequencers wieder in Klartext gewandelt werden. PSExec ist auch im Stammver-zeichnis dieses Skripts abzulegen. Mit PSExec ist es auch möglich, durch ein Autologin eine GUI starten zu lassen. Für manche Vorgänge ist das zwingend erforderlich. Der Vorgang beginnt mit der Definition der Kommandozeile.

$Command = 'powershell.exe -ExecutionPolicy remotesigned -NonInteractive -Command "& C:\CreateSequence.ps1 "' -f $appvname

Write-Host "This will take longer. At least three minutes to sequence $appvname" -ForegroundColor Yellow

& $($RootDirectory + "\psexec.exe") \\$sequencer -accepteula "-u" $vmuser "-p" $ClearPassword CMD /C "$Command || EXIT /B 1" 2> $psExecErrorOutput

Abschließend kann das Resultat auf das Controller-System kopiert und die Ausführungsschleife geschlossen werden.

#Copy the result back to the controler
Write-Host "Copy Results"
if(-not (Test-path $($RootDirectory + "\Output_AppV"))) {new-item $($RootDirectory + "\Output_AppV") -ItemType directory}
copy $('\\' + $sequencer +'\c$\sequence\') -Destination $($RootDirectory + "\Output_AppV\") -Recurse -Force

}

Write-Host "Finished packaging"
Disconnect-VIServer -Server $vc -Confirm:$false

Die Pakete liegen nach der Erstellungsprozedur im Output_AppV Verzeichnis.

Dort können die Pakete gleich wieder mit einem kleinen PowerShell-Befehl getestet werden.

Get-ChildItem E:\Output_AppV\*.appv -Recurse | Add-AppvClientPackage | Publish-AppvClientPackage

In jedem Fall muss man schauen, was am Ende davon funktioniert. Anders verhält es sich bei einem Ein-satz einer solchen Technik zur Paketkonvertierung, denn konvertierte Pakete sind schon konfiguriert.

Related Posts

Leave Comments