#*================================================================================= # Copyright © 2012, Microsoft Corporation. All rights reserved. #*================================================================================= #function find-typeassembly($classname) # return assembly #function import-cs([string] $classname, [string] $sourcefile, [string] $sourcetext, [switch] $force) #[bool] function log-cwosscriptexception() #function Save($xmldoc, $path) #function Set-PSVersionTable #*================================================================================= $null = [reflection.assembly]::loadwithpartialname("system.windows.forms") #*================================================================================= #Function: find-typeassembly #Purpose: Search all loaded assemblies for the named type #Return: assembly #*================================================================================= function find-typeassembly($typename) # return assembly { foreach ($assembly in [appdomain]::currentdomain.getassemblies()) { foreach ($type in $assembly.gettypes()) { if ($type.fullname -eq $typename) { return $assembly } } # $type } # $assembly return $null } # find-classassembly #*================================================================================= #Function: cwos-stack #Purpose: Wrap current stack trace as a multi line string. #Param: optional $format -- default $null is 'long' #Param: optional $maxparamlength -- -1 is full, default 0 is interpreted as 50 #Return: [string] #*================================================================================= function cwos-stack([string] $stackformat, [int] $maxparamlength) { if ([string]::isnullorempty($stackformat)) { $stackformat = 'long' } if ($maxparamlength -eq 0) { $maxparamlength = 50 } if (@(get-command *get-pscallstack).length -eq 0) { return '(Stack trace is unavailable)' } $callstack = @( &{ get-pscallstack trap [management.automation.commandnotfoundexception] { throw 'Failed obtain call stack' } } ) $trimargs = { # debug: [console]::error.writeline("trimargs $($_.command) $($_.arguments)") $args = $_.arguments if ($maxparamlength -gt 1 -and $_.arguments.length -gt $maxparamlength) { $x = $_ | select * $x.arguments = '[' + $_.arguments.substring(1, $maxparamlength - 2) + '...]' return $x } else { return $_ } } # $trimargs switch ($stackformat) { 'long' { $f = { "$($_.location): $($_.command)$($_.arguments)" } } # long } # switch $l = @( $callstack |% $trimargs |% $f ) return [string]::join("`n", $l) } # cwos-stack #*================================================================================= #Function: Import-CS #Purpose: Encapsulate loading of C# code. # The sourcefiles are ignored when the sourcetext is specified. # The classname should be declared by the c# source to indicate that the source was successfully loaded. #Throw: If $sourcefile is missing and $sourcetext is blank. #Throw: If $classname is not declared by the c# source. #Throw: If the class already exists, and -force is requested. Re-loading a class is not supported. #Return: type #Notice: The source may declare many types, and NOT necessary to use the returned type reference. #Notice: The source files should have any import statements INSIDE the namespace. # At runtime, the c# code will fail to compile if import statements are outside # namespace in the second and following files. #*================================================================================= function import-cs([string] $classname, [string[]] $sourcefile, [string] $sourcetext, [switch] $force, [string[]] $referencedassemblies,[string]$Language = "CSharp",[string]$CodeDomProvider) { $type = $classname -as [type] if ($type -ne $null) { if ($force) { # Remove the old instance of this class throw "Unloading assemblies is not supported in this version" } else { # The class has already been loaded return $type } } if ($sourcetext -lt ' ') { foreach ($file in $sourcefile) { if (test-path $file) { $sourcetext += "`n" + [string]::join("`n", (get-content $file)) } else { $title = "Missing c# source $file" [string] $message = $myinvocation.positionmessage $xml = $myinvocation | convertto-xml update-diagreport ` -xml $xml ` -id 'embeddedcodemissing' ` -name $title ` -description $message ` -verbosity 'error' throw "Source file $file does not exist" } } # for $file } &{ $compilefile = 'compilefile.txt' $count = $error.count if(![string]::IsNullOrEmpty($CodeDomProvider)) { $out = add-type ` -typedefinition $sourcetext ` -referencedassemblies $referencedassemblies -CodeDomProvider $CodeDomProvider ` -ignorewarnings 2> $compilefile } else { $out = add-type ` -typedefinition $sourcetext ` -referencedassemblies $referencedassemblies -Language $language ` -ignorewarnings 2> $compilefile } $compileresult = cat $compilefile if ($error.count -ne $count) { $e = $error[0] $title = "Error " + $e.FullyQualifiedErrorId [string] $position = $e.invocationinfo.positionmessage [string] $message = $e.exception $message += $position $xml = @(cwos-stack) + $e + $sourcefile + $stdout + $stderr + $out | convertto-xml update-diagreport ` -xml $xml ` -id 'embeddedcodeerror' ` -name 'Embedded Code Error' ` -description $position ` -verbosity 'error' throw "Error compiling $sourcefile" } trap { #$stdout = cat $outfile #$stderr = cat $errfile $e = $error[0] $title = "Error " + $e.FullyQualifiedErrorId [string] $position = $e.invocationinfo.positionmessage [string] $message = $e.exception $message += $position $xml = @(cwos-stack) + $sourcefile + $compileresult + $out + $e | convertto-xml update-diagreport ` -xml $xml ` -id 'embeddedcodeerror' ` -name 'Embedded Code Error' ` -description $position ` -verbosity 'error' throw "Error compiling $sourcefile" } } # compile $type = $classname -as [type] if ($type -eq $null) { $xml = @(cwos-stack) + $sourcefile + $compileresult + $out + $e | convertto-xml update-diagreport ` -xml $xml ` -id 'embeddedcodeerror' ` -name 'Embedded Code Error' ` -description $position ` -verbosity 'error' throw "The type [$classname] was not defined after compiling files [$sourcefile]" } return $type } # Import-CS #*================================================================================= #Function : log-cwosscriptexception #Purpose : Writes the latest script exception to the diagnostic report #Return : [bool] $continue -- the script should terminate if $continue is false. #*================================================================================= function log-cwosscriptexception() { $e = $error[0] $title = "Error " + $e.FullyQualifiedErrorId [string] $position = $e.invocationinfo.positionmessage [string] $message = $e.exception $message += $position [bool] $continue = $false $flags = [windows.forms.messageboxbuttons]::okcancel $result = [windows.forms.messagebox]::show($message, $title, $flags) $continue = $result -eq [windows.forms.dialogresult]::ok ##line 219 $xml = $e | convertto-xml update-diagreport ` -xml $xml ` -id 'scripterror' ` -name 'Script Error' ` -description $position ` -verbosity 'error' return $continue trap { $null = [reflection.assembly]::loadwithpartialname("system.windows.forms") $message = "Error while writing error report" $message += $error[0].invocationinfo.positionmessage $message += $error[0].exception [windows.forms.messagebox]::show($message) } } # log-cwosscriptexception #*================================================================================= #Function : Set-PSVersionTable #Purpose : Check system for current PowerShell Version #Return : void #*================================================================================= function Set-PSVersionTable { if (!(test-path variable:PSVersionTable)) { $myPSVersionTable = @{} [Version]$CLRVersion = $([System.Reflection.Assembly]::GetExecutingAssembly().ImageRuntimeVersion).TrimStart("v") [Version]$BuildVersion = $(Get-WmiObject Win32_OperatingSystem).Version [Version]$PSVersion = "1.0" [Version]$WSManStackVersion = "0.0" [Array]$PSCompatibleVersions = @($PSVersion) [Version]$SerializationVersion = "0.0.0.0" [Version]$PSRemotingProtocolVersion = "0.0.0.0" $myPSVersionTable.Add('CLRVersion', $CLRVersion) $myPSVersionTable.Add('BuildVers$PSion', $BuildVersion) $myPSVersionTable.Add('PSVersion', $PSVersion) $myPSVersionTable.Add('WSManStackVersion', $WSManStackVersion) $myPSVersionTable.Add('PSCompatibleVersions', $PSCompatibleVersions) $myPSVersionTable.Add('SerializationVersion', $SerializationVersion) $myPSVersionTable.Add('PSRemotingProtocolVersion', $PSRemotingProtocolVersion) Set-Variable -Name PSVersionTable -Scope Global -Value $myPSVersionTable -Option Constant } } Set-PSVersionTable # If Powershell Version is less than 2.0 load compatibility scripts if ($PSVersionTable.PSVersion -lt '2.0') { . .\utils_PowerShell_1_0.ps1 } #*================================================================================= #Function : Save #Purpose : will check the version and accordingly save input xml to a file #Return : #*================================================================================= function Save() { param($xmldoc,$path) trap [Exception] {continue;} if($PSVersionTable.PSVersion -lt '2.0') { if($xmldoc -ne $null) { $xmldoc | out-file $path -Force } } else { if($xmldoc -ne $null) { $xmldoc.save($path) } } } #*================================================================================= #End #*================================================================================= #*================================================================================= #Arm Compression code #*================================================================================= Function GetARMCompression() { $str = @' using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.IO.Compression; namespace Compressions { public class OutputDataPackage { string fileName; ZipArchive z; FileStream fileStream; ZipArchiveEntry zae; public string FileName { get { return fileName; } } public OutputDataPackage() { string dt = String.Format("{0:yyyy-MM-dd_hh-mm-ss}", DateTime.Now); string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); fileName = filePath +@"\RoamingLog"+dt+".zip"; fileStream = new FileStream(fileName, FileMode.Create); z = new ZipArchive(fileStream, ZipArchiveMode.Create); } public OutputDataPackage(string outputPackagePath) { DateTime dt = DateTime.Now; this.fileName = outputPackagePath; fileStream = new FileStream(this.fileName, FileMode.Create); z = new ZipArchive(fileStream, ZipArchiveMode.Create); } public OutputDataPackage(string outputPackagePath,bool overwrite) { if(overwrite) { DateTime dt = DateTime.Now; this.fileName = outputPackagePath; fileStream = new FileStream(this.fileName, FileMode.Create); z = new ZipArchive(fileStream, ZipArchiveMode.Create); } else { DateTime dt = DateTime.Now; this.fileName = outputPackagePath; fileStream = new FileStream(this.fileName, FileMode.OpenOrCreate); z = new ZipArchive(fileStream, ZipArchiveMode.Update); } } // Add a file to the package using the specified path on disk and path in package // Example call: "outputPackage.AddFile("temp.txt", new Uri("/temp.txt", UriKind.RelativeOrAbsolute));" // public void AddFile(String pathOnDisk, String pathInZip) { zae = z.CreateEntry(pathInZip, CompressionLevel.Fastest); FileStream fs = new FileStream(pathOnDisk, FileMode.Open, FileAccess.Read); using (Stream s = zae.Open()) { fs.CopyTo(s); } fs.Close(); } // Saves the package out public void Close() { z.Dispose(); } } } '@ add-type $str -ReferencedAssemblies "System.IO.Compression" } #**************************************************************************************************** #ARM-Zip #Params $srcdir,$destDir - Works on all Win 8 including ARM #**************************************************************************************************** Function ARM-Zip() { param([string]$srcdir,$destDir) GetARMCompression $obj = new-object Compressions.OutputDataPackage($destDir) get-childitem $srcdir -force -recurse -ea SilentlyContinue|?{!([system.io.directory]::Exists($_.FullName))}|%{ $relativepath = [system.io.path]::GetFullPath($_.FullName).SubString([system.io.path]::GetFullPath($srcdir).Length + 1); $obj.AddFile($_.FullName.ToString(),$relativepath.ToString() -as [system.uri]) 2>$null } $obj.Close() } #*================================================================================= #Get-SizeFormat #*================================================================================= function Get-SizeFormat () { param($length) if($length -gt 1gb) { $use=1gb;$ext="GB" } elseif($length -gt 1mb) { $use=1mb;$ext="MB" } else { $use=1kb;$ext="KB" } $size = [math]::Round($length/$use,2) $size=$size.ToString()+"$ext" return $size } # Function to check whether the current machine is domain joined Function Test-DomainJoined() { return (Get-WmiObject -query "select * from win32_ntdomain where Status ='OK'") -ne $null } # Function to wait for expected service status function WaitFor-ServiceStatus([string]$serviceName=$(throw "No service name is specified"), [ServiceProcess.ServiceControllerStatus]$serviceStatus=$(throw "No service status is specified")) { [ServiceProcess.ServiceController]$sc = New-Object "ServiceProcess.ServiceController" $serviceName [TimeSpan]$timeOut = New-Object TimeSpan(0,0,0,5,0) $sc.WaitForStatus($serviceStatus, $timeOut) } # Function to update time source Function Update-TimeSource([string]$timeSource = $(throw "No time source is specified")) { w32tm.exe /config /update /manualpeerlist:"$timeSource" }