Buongiorno Mr Script! Creazione di file CAB con Windows PowerShell

The Microsoft Scripting Guys

Contenuto

Espansione dei file CAB
Utilizzare l'utilità makecab.exe

uno dei mio filmati preferiti tasto di scelta (" Elisabetta rapida") è stato su un ragazzo che è stato un smuggler dei dati in futuro. Ha sarebbe viaggio in paesi diversi e incontri con i client. Egli aveva una presa surgically implanted in base la testina di e i clienti necessario collegare i dispositivi ricerca Zune negli importi rilevanti presa e trasferimento di dati nel suo cervello. Poiché questo smuggler dei dati era suo cervello partizionata e utilizzava evidently autorizzazioni file NTFS, non ha disponeva dei diritti alla sezione della sua cervello smuggling dati. I dati sono sicuri di conseguenza, anche da del smuggler proprio wandering pensieri. In una scena, il client intende lui courier una quantità di dati rilevanti ma evidently nostro smuggler non dispone di una capacità sufficiente per eseguire i dati così tanto. Pertanto, cosa ha ha? Ha compressi suo cervello, mi piace.

Compressione dei dati non solo fodder valida per i filmati, è altrettanto utile per gli amministratori di rete. È tutti conoscono probabilmente utilizzare, diverse utilità di compressione di file. È possibile utilizzarli ogni settimana per l'invio capitoli del mio libro nuovo tramite posta elettronica a mio editor a Microsoft Press. È possibile farlo non buona parte perché è vincolata della larghezza di banda, ma perché si dispone di quote di posta elettronica che consente di limitare la dimensione dei messaggi elettronica che è possibile memorizzare, inviare e ricevere. Hanno utilizzato utilità di compressione di file anche quando necessari per archiviare il file da computer portatile in uno dei diversi dischi portatili mobile intorno a mio ufficio.

Quando utilizzato per tutto il mondo docente script workshop di viaggio, sarebbe necessario regolarmente, "come possibile è possibile comprimere i file tramite script?" E desidera rispondere, "è necessario acquistare un'utilità di terze parti che supporta opzioni della riga di comando." Un giorno, è stato lettura mediante il Registro di sistema ed È stato eseguito in un oggetto COM denominato (aspetto interessante è che sufficientemente) makecab.makecab. Si supponga hmm, ciò che si che tale oggetto? Yep, è vero. Consente di rendere i file CAB, elevata compressione file utilizzati da varie applicazioni per la creazione del package e distribuzione. Ma non esiste alcuna operazione per interrompere un amministratore di rete enterprising o script guru da appropriating questi strumenti per se stessi. E solo ciò che faremo. Iniziamo con lo script nella Figura 1 .

Nella figura 1 CreateCab.ps1

Param(
  $filepath = "C:\fso", 
  $path = "C:\fso\aCab.cab",
  [switch]$debug
  )
Function New-Cab($path,$files)
{
 $makecab = "makecab.makecab"
 Write-Debug "Creating Cab path is: $path"
 $cab = New-Object -ComObject $makecab
 if(!$?) { $(Throw "unable to create $makecab object")}
 $cab.CreateCab($path,$false,$false,$false)
 ForEach ($file in $files)
 {
 $file = $file.fullname.tostring()
 $fileName = Split-Path -path $file -leaf
 Write-Debug "Adding from $file"
 Write-Debug "File name is $fileName"
 $cab.AddFile($file,$filename)
 }
 Write-Debug "Closing cab $path"
 $cab.CloseCab()
} #end New-Cab

# *** entry point to script ***
if($debug) {$DebugPreference = "continue"}
$files = Get-ChildItem -path $filePath | Where-Object { !$_.psiscontainer }
New-Cab -path $path -files $files

CreateCab.ps1 –filepath C:\fso1

La prima operazione da eseguire consiste nel creare alcuni parametri della riga di comando utilizzando l'istruzione di parametro. L'istruzione il parametro deve essere la prima riga noncommented nello script. Quando lo script viene eseguito nella console di Windows PowerShell oppure da all'interno di un editor di script, i parametri della riga di comando vengono utilizzati per controllare il modo in cui che viene eseguito lo script. In questo modo, non è necessario modificare lo script ogni volta che si desidera creare un file CAB da un'altra directory. Si solo necessario fornisce un nuovo valore per il parametro –filepath, come illustrato di seguito:

La buona cosa sui parametri della riga di comando è che utilizzano completamento parziale del parametro, ovvero è necessario specificare solo sufficientemente del parametro che sia univoco. Di conseguenza, è possibile utilizzare una sintassi della riga di comando come questo:

CreateCab.ps1 –f c:\fso1 –p c:\fso2\bcab.cab –d

Questa sintassi necessario cercare la directory c:\fso1 e ottenere tutti i file. Quindi necessario creare un file CAB denominato bcab.cab nella cartella fso2 disattivare l'unità c:\. Inoltre potrebbe produrre informazioni di debug mentre era in esecuzione. Si noti che il parametro –debug è un parametro switched, che significa che influenza lo script solo quando è presente. Ecco la sezione dello script CreateCab.ps1 rilevante:

Param(
  $filepath = "C:\fso", 
  $path = "C:\fso\aCab.cab",
  [switch]$debug
  )

Ora è verrà creare la funzione CAB di nuovo, che accetta due parametri di input, –path e –files:

Function New-Cab($path,$files)

È possibile assegnare l'ID di programma, makecab.makecab per makecab una variabile denominata $, che verrà rendere più semplice per la lettura dello script. Questo è anche di un'ottima soluzione per inserire la prima istruzione di debug di scrittura:

{
 $makecab = "makecab.makecab"
 Write-Debug "Creating Cab path is: $path"

Quindi verrà creato l'oggetto COM:

 $cab = New-Object -ComObject $makecab

Un bit di controllo degli errori è in ordine, che può essere eseguite utilizzando il simbolo $? variabile automatica:

 if(!$?) { $(Throw "unable to create $makecab object")}

Se nessun errore si è verificato durante il tentativo di creare l'oggetto makecab.makecab, è possibile utilizzare l'oggetto contenuto nella variabile $ cab e chiamare il metodo CreateCab:

 $cab.CreateCab($path,$false,$false,$false)

Una volta creato il file CAB, è possibile aggiungervi file utilizzando l'istruzione ForEach:

 ForEach ($file in $files)
 {
 $file = $file.fullname.tostring()
 $fileName = Split-Path -path $file -leaf

Dopo aver convertito il nome completo del file in una stringa e rimuovere le informazioni di directory utilizzando il cmdlet percorso doppia, è necessario includere un'altra istruzione debug di scrittura per consentire all'utente dello script di sapere cosa sta succedendo, in questo modo:

 Write-Debug "Adding from $file"
 Write-Debug "File name is $fileName"

È aggiungere il file del file CAB:

 $cab.AddFile($file,$filename)
 }
 Write-Debug "Closing cab $path"

Per chiudere il file CAB, è necessario utilizzare il metodo CloseCab:

 $cab.CloseCab()
} #end New-Cab

Ora andiamo il punto di ingresso di script. Innanzitutto è verificare se lo script viene essere eseguito in modalità debug cercando la variabile di debug $. Se la variabile di debug $ non è presente, non devi effettuare alcuna operazione. Se è presente, è necessario impostare il valore di DebugPreference variabile $ per continuare, che consente le istruzioni di debug di scrittura per la stampa su schermo. Il DebugPreference $ è impostazione predefinita per silentlycontinue, significa andare oltre il comando senza eseguire qualsiasi operazione. Di seguito è riportato il codice:

if($debug) {$DebugPreference = "continue"}

A questo punto è necessario ottenere un insieme di file. A tale scopo, è possibile utilizzare il cmdlet ChildItem Get:

$files = Get-ChildItem -path $filePath | 
 Where-Object { !$_.psiscontainer }

Quindi di passare all'insieme alla funzione CAB di nuovo come illustrato di seguito:

New-Cab -path $path -files $files

Quando si esegue lo script CreateCab.ps1 in modalità di debug, si noterà output come illustrato nella Nella figura 2 .

fig02.gif

Nella figura 2 CreateCab.ps1 in esecuzione in modalità di debug

Espansione dei file CAB

È Impossibile utilizzare l'oggetto makecab.makecab per espandere il file CAB perché non ha un metodo di espansione. Né utilizzare l'oggetto makecab.expandcab perché non esiste. Ma la possibilità di espandere un file CAB inerente la shell di Windows in modo da poter utilizzare l'oggetto shell. Per accedere alla shell, è possibile utilizzare l'oggetto COM Shell.Application, come illustrato nello script ExpandCab.ps1 nella Figura 3 .

Nella figura 3 ExpandCab.ps1

Param(
  $cab = "C:\fso\acab.cab",
  $destination = "C:\fso1",
  [switch]$debug
  )
Function ConvertFrom-Cab($cab,$destination)
{
 $comObject = "Shell.Application"
 Write-Debug "Creating $comObject"
 $shell = New-Object -Comobject $comObject
 if(!$?) { $(Throw "unable to create $comObject object")}
 Write-Debug "Creating source cab object for $cab"
 $sourceCab = $shell.Namespace($cab).items()
 Write-Debug "Creating destination folder object for $destination"
 $DestinationFolder = $shell.Namespace($destination)
 Write-Debug "Expanding $cab to $destination"
 $DestinationFolder.CopyHere($sourceCab)
}

# *** entry point ***
if($debug) { $debugPreference = "continue" }
ConvertFrom-Cab -cab $cab -destination $destination

Lo script crea innanzitutto i parametri della riga di comando nello stesso ha CreateCab.ps1:

Param(
  $cab = "C:\fso\acab.cab",
  $destination = "C:\fso1",
  [switch]$debug
  )

Successivamente creata il CAB ConvertFrom funzione, che accetta due parametri della riga di comando, uno che contiene il file CAB e uno contenente la destinazione per espandere i file:

Function ConvertFrom-Cab($cab,$destination)

A questo punto si crea un'istanza dell'oggetto Shell.Application, un oggetto molto potente con un numero di metodi utili. Nella figura 4 è illustrato i membri dell'oggetto Shell.Application.

Figura 4 membri dell'oggetto Shell.Application
Nome MemberType Definizione
AddToRecent Metodo Annulla AddToRecent Variant, stringa
BrowseForFolder Metodo Cartella BrowseForFolder (int, string, int, valore di tipo Variant)
CanStartStopService Metodo CanStartStopService Variant (string)
CascadeWindows Metodo Annulla CascadeWindows)
ControlPanelItem Metodo ControlPanelItem void (stringa)
EjectPC Metodo Annulla EjectPC)
Esplorare Metodo Esplora void (Variant)
ExplorerPolicy Metodo ExplorerPolicy Variant (string)
FileRun Metodo Annulla FileRun)
FindComputer Metodo Annulla FindComputer)
FindFiles Metodo Annulla FindFiles)
FindPrinter Metodo Annulla FindPrinter (string, stringa, stringa)
GetSetting Metodo BOOL GetSetting (int)
GetSystemInformation Metodo GetSystemInformation Variant (string)
Guida Metodo void () della Guida in linea
IsRestricted Metodo int IsRestricted (string, stringa)
IsServiceRunning Metodo IsServiceRunning Variant (string)
MinimizeAll Metodo Annulla MinimizeAll)
NameSpace Metodo Cartella NameSpace (Variant)
Apri Metodo Apri void (Variant)
RefreshMenu Metodo Annulla RefreshMenu)
ServiceStart Metodo ServiceStart variante, un valore Variant (string)
ServiceStop Metodo ServiceStop variante, un valore Variant (string)
SetTime Metodo Annulla SetTime)
ShellExecute Metodo Annulla ShellExecute (string, Variant Variant Variant, valore di tipo Variant)
ShowBrowserBar Metodo ShowBrowserBar variante, un valore Variant (string)
ShutdownWindows Metodo Annulla ShutdownWindows)
Sospensione Metodo void ()
TileHorizontally Metodo Annulla TileHorizontally)
TileVertically Metodo Annulla TileVertically)
ToggleDesktop Metodo Annulla ToggleDesktop)
TrayProperties Metodo Annulla TrayProperties)
UndoMinimizeALL Metodo Annulla UndoMinimizeALL)
Windows Metodo Windows IDispatch)
WindowsSecurity Metodo Annulla WindowsSecurity)
Applicazione Proprietà () Dell'applicazione IDispatch {get}
Padre Proprietà IDispatch padre () {get}

Poiché si intende utilizzare più volte il nome dell'oggetto COM, è buona norma assegnare l'ID di programma dell'oggetto COM a una variabile. Sarà possibile utilizzare la stringa con il cmdlet oggetto nuovo, nonché quando viene fornito commenti e suggerimenti per l'utente. Ecco la riga di codice che assegna l'ID di programma Shell.Application a una stringa.

{
 $comObject = "Shell.Application"

Per fornire commenti e suggerimenti, è possibile utilizzare il cmdlet debug di scrittura con un messaggio che si sta tentando di creare l'oggetto Shell.Application:

 Write-Debug "Creating $comObject"

È effettivamente verrà quindi creare l'oggetto:

 $shell = New-Object -Comobject $comObject

Quindi è verificare la presenza degli errori. Per tale scopo, è possibile utilizzare la variabile $ automatico?, che indica se l'ultimo comando completata. È un valore Boolean true/false. È possibile utilizzare questo fatto per semplificare il codice. Si utilizza il non operatore!, in combinazione con un se istruzione. Se la variabile non è true, utilizzare l'istruzione throw genera un errore e interrompere l'esecuzione dello script, in questo modo:

 if(!$?) { $(Throw "unable to create $comObject object")}

Se lo script crea correttamente l'oggetto Shell.Application, forniamo alcuni commenti e suggerimenti:

 Write-Debug "Creating source cab object for $cab"

Il passaggio successivo nell'operazione consiste di connettersi al file CAB. A tale scopo, è possibile utilizzare il metodo dello spazio dei nomi dall'oggetto Shell.Application. Si tratta di un altro passaggio importante, pertanto è opportuno utilizzare un'altra istruzione di debug scrittura come un indicatore di stato per l'utente:

 $sourceCab = $shell.Namespace($cab).items()
 Write-Debug "Creating destination folder object for $destination"

È ora connettersi alla cartella di destinazione. A tale scopo, utilizzare il metodo dello spazio dei nomi, quindi un'altra istruzione debug di scrittura per consentire all'utente sapere quale cartella è stata effettivamente connessi a:

 $DestinationFolder = $shell.Namespace($destination)
 Write-Debug "Expanding $cab to $destination"

Con tutti i che preparazione dall'area di lavoro, il comando effettivo per l'espansione del file CAB è alquanto anticlimactic. Utilizzare il metodo CopyHere dall'oggetto cartella che viene memorizzato nella variabile $ DestinationFolder. È possibile assegnare il riferimento al file CAB memorizzato nella variabile $ sourceCab come parametro di input in questo modo:

 $DestinationFolder.CopyHere($sourceCab)
}

Il punto iniziale allo script esegue due operazioni. Innanzitutto, controlla la presenza della variabile $ debug. Se $ debug è presente, imposta il debugPreference $ per continuare a imporre il cmdlet di debug di scrittura per stampare i messaggi nella finestra della console. In secondo luogo, chiama la funzione CAB ConvertFrom e passa il percorso del file cab dal parametro della riga di comando –cab e la destinazione per i file espansi dal parametro –destination:

if($debug) { $debugPreference = "continue" }
ConvertFrom-Cab -cab $cab -destination $destination

Quando si esegue lo script ExpandCab.ps1 in modalità di debug, verrà visualizzato simile a quella di output Nella figura 5 .

fig05.gif

Nella figura 5 ExpandCab.ps1 in esecuzione in modalità di debug

Utilizzare l'utilità makecab.exe

Se si esegue questi due script in Windows Server 2003 o Windows XP, sarà necessario gli eventuali problemi, ma l'oggetto COM makecab.makecab non esiste in Windows Vista o versione successiva. Questo misfortune non arrestare script determinato, tuttavia, perché è sempre possibile utilizzare l'utilità makecab.exe dalla riga di comando. A tale scopo, è possibile utilizzare lo script CreateCab2.ps1, illustrato nella Figura 6 .

Nella figura 6 CreateCab2.ps1

Param(
  $filepath = "C:\fso", 
  $path = "C:\fso1\cabfiles",
  [switch]$debug
  )
Function New-DDF($path,$filePath)
{
 $ddfFile = Join-Path -path $filePath -childpath temp.ddf
 Write-Debug "DDF file path is $ddfFile"
 $ddfHeader =@"
;*** MakeCAB Directive file
;
.OPTION EXPLICIT      
.Set CabinetNameTemplate=Cab.*.cab
.set DiskDirectory1=C:\fso1\Cabfiles
.Set MaxDiskSize=CDROM
.Set Cabinet=on
.Set Compress=on
"@
 Write-Debug "Writing ddf file header to $ddfFile" 
 $ddfHeader | Out-File -filepath $ddfFile -force -encoding ASCII
 Write-Debug "Generating collection of files from $filePath"
 Get-ChildItem -path $filePath | 
 Where-Object { !$_.psiscontainer } |
 ForEach-Object `
 { 
 '"' + $_.fullname.tostring() + '"' | 
 Out-File -filepath $ddfFile -encoding ASCII -append
 }
 Write-Debug "ddf file is created. Calling New-Cab function"
 New-Cab($ddfFile)
} #end New-DDF

Function New-Cab($ddfFile)
{
 Write-Debug "Entering the New-Cab function. The DDF File is $ddfFile"
 if($debug)
 { makecab /f $ddfFile /V3 }
 Else
 { makecab /f $ddfFile }
} #end New-Cab

# *** entry point to script ***
if($debug) {$DebugPreference = "continue"}
New-DDF -path $path -filepath $filepath

Come con gli script CreateCab2.ps1 crea innanzitutto un paio di parametri della riga di comando:

Param(
  $filepath = "C:\fso", 
  $path = "C:\fso1\cabfiles",
  [switch]$debug
  )

Quando si esegue lo script con l'opzione –debug, l'output sarà simile alle informazioni che verranno visualizzate in Nella figura 7 .

fig07.gif

Nella figura 7 CreateCab2.ps1 in esecuzione in modalità di debug

Lo script crea quindi la funzione DDF nuovo, che crea un file .ddf base che viene utilizzato dal programma MakeCab.exe per creare il file CAB. La sintassi per questi tipi di file è documentata nel Microsoft Cabinet Software Development Kit. Dopo aver utilizzato la parola chiave funzione per creare la funzione DDF nuovo, utilizzare il cmdlet percorso join per creare il percorso di file nel file .ddf temporaneo. È possibile concatenare unità, la cartella e il nome del file insieme ma questo potrebbe risultare un'operazione complesso e tendente all'errore. Ottimale, è sempre necessario utilizzare il cmdlet percorso join per creare percorsi del file, in questo modo:

Function New-DDF($path,$filePath)
{
 $ddfFile = Join-Path -path $filePath -childpath temp.ddf

Per fornire un po'di commenti e suggerimenti per l'utente se lo script viene eseguito con l', opzione di debug, utilizzare il cmdlet debug scrittura come illustrato di seguito:

 Write-Debug "DDF file path is $ddfFile"

A questo punto è necessario creare la prima parte del file .ddf. A tale scopo, è possibile utilizzare un'espansione qui, stringa, ovvero che non sarà necessario riguarda manualmente con l'escape di caratteri speciali. Ad esempio, commenti in un file .ddf sono preceduti da un punto e virgola, che è un carattere riservato in Windows PowerShell. Se si tenta di creare il testo senza una qui, stringa, è necessario eseguire l'escape ciascuno dei punti e virgola per evitare errori in fase di compilazione. Utilizzando un'espansione qui, stringa, è possibile sfruttare l'espansione delle variabili. Un qui-stringa inizia con la e commerciale e un segno di virgolette e termina con un segno di virgolette una e commerciale (&):

 $ddfHeader =@"
;*** MakeCAB Directive file
;
.OPTION EXPLICIT      
.Set CabinetNameTemplate=Cab.*.cab
.set DiskDirectory1=C:\fso1\Cabfiles
.Set MaxDiskSize=CDROM
.Set Cabinet=on
.Set Compress=on
"@

Quindi potrebbe si desidera aggiungere commenti e suggerimenti tramite il cmdlet debug scrittura:

 Write-Debug "Writing ddf file header to $ddfFile" 

Ora si sono alla parte potrebbero verificarsi alcuni problemi. Il file di .ddf deve essere pure ASCII. Per impostazione predefinita, Windows PowerShell utilizza Unicode. Per assicurarsi che sia disponibile un file ASCII, è necessario utilizzare il cmdlet di Out-File. Nella maggior parte dei casi, è possibile evitare di utilizzare Out-File utilizzando le frecce il reindirizzamento di file, ma non è uno di questi casi. Ecco la sintassi:

 $ddfHeader | Out-File -filepath $ddfFile -force 
-encoding ASCII

Si desidera probabilmente fornire alcune informazioni di debug con debug scrittura prima è raccogliere l'insieme di file tramite il cmdlet ChildItem Get:

 Write-Debug "Generating collection of files from $filePath"
 Get-ChildItem -path $filePath | 

È importante escludere cartelle dall'insieme perché MakeCab.exe non è in grado di comprimere le cartelle. A tale scopo, utilizzare il WHERE-Object con un non operatore che informa che l'oggetto non è un contenitore:

 Where-Object { !$_.psiscontainer } |

Successivamente, è necessario utilizzare tutti i file come si tratta di attraverso la pipeline. A tale scopo, utilizzare il cmdlet oggetto ForEach. Poiché oggetto ForEach viene un cmdlet, a differenza di un'istruzione di linguaggio, le parentesi graffe devono essere sulla stessa riga come nome del cmdlet oggetto ForEach. Il problema con questo è che vi sia una tendenza a seppellire le parentesi graffe nel codice. Ottimale, desidera allineare le parentesi graffe a meno che il comando non sia molto breve come il precedente comando WHERE-Object. A tal fine, tuttavia, è necessario utilizzare il carattere di continuazione di riga (backtick). Conosce alcuni sviluppatori che consente di evitare di continuazione di riga come il Peste, ma RITENGO che allineamento le parentesi graffe è più importante in quanto facile il codice di lettura. Di seguito è l'inizio del cmdlet oggetto ForEach:

 ForEach-Object `

Poiché il file .ddf utilizzato da MakeCab.exe è testo ASCII, sarà necessario convertire la proprietà fullname dell'oggetto System.IO.fileinfo restituito per il cmdlet ChildItem Get in una stringa. Inoltre, poiché si potrebbero hanno file con i nomi di spazi, è opportuno per racchiudere il valore di fullname file in un set di virgolette:

 { 
 '"' + $_.fullname.tostring() + '"' | 

Quindi pipeline di nomi di file per il Out-File cmdlet, assicurandosi che per specificare la codifica ASCII e per utilizzare l'opzione –append per evitare la sovrascrittura tutto il resto del file di testo:

 Out-File -filepath $ddfFile -encoding ASCII -append
 }

Ora è possibile forniscono agli utenti debug che un altro aggiornamento e quindi chiamare la funzione CAB nuovo:

 Write-Debug "ddf file is created. Calling New-Cab function"
 New-Cab($ddfFile)
} #end New-DDF

Quando si immette la funzione CAB di nuovo, è inoltre possibile fornire le informazioni per l'utente:

Function New-Cab($ddfFile)
{
 Write-Debug "Entering the New-Cab function. The DDF File is $ddfFile"

Successivamente, se lo script viene eseguito con l'opzione –debug, è possibile utilizzare /V parametro del MakeCab.exe che fornisce informazioni dettagliate di debug (3 è completo dettaglio; 0 è none). Se lo script non viene eseguito con l'opzione –debug, non si desidera occupi schermo con una quantità eccessiva informazioni in modo deve osserva predefinito l'utilità:

 if($debug)
 { makecab /f $ddfFile /V3 }
 Else
 { makecab /f $ddfFile }
} #end New-Cab

Il punto di ingresso per lo script di verifica per verificare se il simbolo $ debug variabile è presente. Se è, la variabile di automatico del debugPreference $ è impostata per continuare e le informazioni di debug verranno visualizzata tramite il cmdlet di debug di scrittura. Una volta eseguito tale controllo, il cmdlet DDF nuovo viene chiamato con i due valori forniti alla riga di comando: il percorso e il percorsofile:

if($debug) {$DebugPreference = "continue"}
New-DDF -path $path -filepath $filepath

Ovvero sull'per articolo di questo mese la compressione e decompressione dei file. Se si ritiene come la testina sta per esplodere, è possibile provare a collegare il Zune l'anno e vedere se è possibile eseguire una delle seguenti questi script per comprimere parte del cervello. Che But…I informa now…it destra funziona solo nei filmati. Errata. Se è non conservare, è necessario arrestare per il centro di TechNet script e lo si è estrarre nostro giornaliero "Hey, Scripting Guy!" articolo. Vedere si presenti.

ed Wilson , un noto esperto di script è l'autore di otto libri, tra cui Windows PowerShell Scripting Guide (2008) e Microsoft Windows PowerShell Step by Step (2007). Ed contiene più di 20 certificazioni del settore, tra cui Microsoft Certified Systems Engineer (MCSE) e informazioni Certified di Systems Security Professional (CISSP). Nel tempo riserva, ha apprezzino woodworking, fotografia subacquee e scuba subacquee. E macchie.

Craig Liebendorfer è wordsmith e longtime editor Web di Microsoft. Craig ancora non ritiene c'è un processo che paga gli lavorare con le parole ogni giorno. Uno dei suoi elementi preferiti è irreverent umorismo in modo che deve adattare destra in questa posizione. Ha considerato suo accomplishment maggiore nella vita da sua figlia magnificent.