Archives

Tag Archive for: ‘powershell’

What is the problem with App-V on Windows 10 Anniversary Update
Microsoft released App-V as an add-on for Windows in the MDOP (Microsoft Desktop Optimization Pack). So I also run App-V to have some hands on experience with applications on my Windows 8.1 and later Windows 10 installation. Last week I upgraded to Windows 10 Anniversary Update 1607, and I run in to errors with App-V applications. My Total Commander session lost all the configuration settings, slow starting or even not starting App-V applications.

App-V is now part of Windows, but only for the Enterprise edition. I am running my private computers on Windows 10 Professional unfortunately. For me it wasn’t such a big problem for missing App-V, but the applications can not be removed as well without a running client.

In this blog I will show how to enable the App-V client again. Be aware that this probably not allowed in the EULA, but you are at least able to remove the packages and stop using App-V.

What are the symptoms of a disabled App-V client
Some of the App-V applications will still start, but it take ages to start. And also the settings and files which are stored in the %appdata% of the Virtual File System are inaccessible:

AppV Error on Windows 10

Running the PowerShell command Enable-AppV is giving the error message ‘Enable-Appv : App-V is not available on this edition of Windows’. The command Get-AppvClientPackage and Get-AppvClientPackage | Remove-AppvClientPackage are not functioning as well:

Enable-AppV not working on Windows 10 Professional

Starting the Microsoft App-V Client is not possible, even after setting the service to start manual or automatic.

Start App-V service width=

How to fix the App-V client and let it start again
The fix is easy, open the registry editor and change the following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AppV\Client\Enabled

To the value 1

2016-08-19_204305 ERIK-P50 erik

After this change the App-V client will start function, and you are also able to remove all the App-V packages and disable it again to be compliant ;-).

App-V running and working on Windows 10 Anniversary Update Professional

In case you want to get rid of all you’re App-V packages run this (be carefull):

Get-AppvClientPackage | Remove-AppvClientPackage
Workplace & VDI Test-automation with Powershell

Why to do test automation with PowerShell?
I was involved in a project to implement a new Virtual Desktop Infrastructure (VDI) within a large company

To ensure the environment is stable and well-functioning all the time on the same way, I made a script to test the basic functionality of the virtual desktop image. The script also measures the time it takes to complete an action, so this can be used to set a baseline for performance measurement.

The basic functionality which is scripted is:

  • Start Outlook and Send an email
  • Can the user browse the internet
  • Open a Word document, Print Preview, Print, and save the document
  • Open an Excel sheet, Save it under a different name
  • Browse the AppV content store
  • Start an AppV application

Other actions can be scripted as well and added to the script.

When the script has run completely with success it will ensure you that the basic functionality is still working.

See the script in action
This video gives a quick overview what kind of actions are scripted and how it works.

Workplace and VDI test automation with PowerShell from EasternNL on Vimeo.

What kind of results do the script make?
When using the script a PDF document is generated which shows the following for each step:

2015-09-23_164405

An example PDF document can be found here: 2015-09-23 163927 Workplace and VDI test-automation with PowerShell.pdf

Also an .su file is generated which has the following content:

2015-08-26    07:23:13.439    07:23:14.48    0.6092069    Excel - start    C:\Users\Erik\AppData\Local\Temp\2015-08-26 07.23.13.439 Excel - start.png

This file is tab-separated and can be imported in Excel or other tools for further investigation.

An example SU file can be found here: test.su

My baseline tools
The script is tested on:

  • Windows 7 with Office 2010
  • Windows 10 with Office 2013

Powershell version 3 or higher is enough to run this script. I am sure this will work on other platforms like Windows 8 e.g. as well.

The iTextSharp module is needed to generate the PDF’s and can be found here: http://sourceforge.net/projects/itextsharp/

Boxcutter.exe is used to make screenshots during the test. Boxcutter can be found here: http://keepnote.org/boxcutter/

Script code
Basically the following code is needed to start Excel:

$excel = new-object -comobject Excel.Application
$excel.visible = $True

Other example is the code to start Internet Explorer:

$ie = new-object -com "InternetExplorer.Application"
$ie.visible = $true

(In a second blog item I will explain how to do the automation of browsing on the internet.)

Basically it is simple, however in my coding some extra steps are involved to measure the start of Excel, and to make a screenshot to ensure everything went well. The Write-Transaction function is included in my module and will write the measured times to the .su file and take the screenshot as well.

$transactionname = "Excel - start"
Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $excel = new-object -comobject Excel.Application
            $excel.visible = $True
            } ) 

In the end of the script the complete .su file is converted to PDF format together with the screenshots.

Conclusion
Windows endpoint testing, for VDI but also for physical desktop can be done with scripts. When launching every day, and eventually on different times of a day the performance and functionality of an Windows desktop can be measured.

The complete script

# load the modules
Import-Module "$(Split-Path -parent $PSCommandPath)\Test-Availability.psm1" -Force
Import-Module "$(Split-Path -parent $PSCommandPath)\iTextSharp.psm1" -Force

# -------------------------------------------
# configure variabeles

$testdocument = "$(Split-Path -parent $PSCommandPath)\testdocument.docx"
$testworkbook = "$(Split-Path -parent $PSCommandPath)\testworkbook.xlsx"
$printer = "Bullzip PDF Printer"
$appvcontentstore = "C:\AppV"

# -------------------------------------------

# Stop if an error has occured, will be handled by the try/catch
$ErrorActionPreference = "Stop"

# Verbose messages on
#$VerbosePreference = "Continue"
# wait time between the steps
$sleepseconds = 1
# temporary path to log the output to
$outputfile = "$($env:temp)\test.su"
if (Test-Path $outputfile) { rm $outputfile }



try {

    # Start Outlook 
        $transactionname = "Outlook - Start"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $outlook = new-object -com "Outlook.Application"
            #$outlook.visible = $true
            $namespace = $outlook.GetNamespace("MAPI")
            $folder = $namespace.GetDefaultFolder(16)
            $folder.Display()
            } )

        # Write email
        # (not sending an email because that is blocked by default in Outlook)
        $transactionname = "Outlook - Write message in draft"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $mail = $outlook.CreateItem(0)
            $mail.Subject = "$(Get-Date -format "yyyy-MM-dd HH:mm:ss") VDI Test Script"
            $mail.To = "user@domain.com"
            $mail.Body = "Testing the VDI functionality with a script"
            $mail.save()
            } )

        # Close Outlook 
        $transactionname = "Outlook - Exit"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $outlook.Quit()
            } )
            
    # Internet Explorer - eastern.nl
        $transactionname = "Internet Explorer - Start"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $ie = new-object -com "InternetExplorer.Application"
            $ie.visible = $true
    
            Set-ForegroundWindow "Internet Explorer"
            } )
    
        # navigate
        $transactionname = "Internet Explorer - www.eastern.nl"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $ie.Navigate("http://www.eastern.nl/")
    
            # wait until the page is ready, all parameters okay and the text Erik van Oost is inside the document
            Wait-InternetExplorer -ie $ie -text "Erik van Oost"
            } )
        
        $transactionname = "Internet Explorer - Quit"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            # Internet Explorer Exit
            $ie.quit()
            } )
	
        # Word
        $transactionname = "Word - Start"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $word=new-object -ComObject "Word.Application"
            $word.visible = $true
            } )
    
        # Document open 
        $transactionname = "Word - Open testfile"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $doc = $word.Documents.Open($testdocument)
            } )

        # Document saven op temp
        $transactionname = "Word - Save testfile"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $filename = "$($env:temp)\test.docx"
            $file_formatcode = 12

            if (Test-Path filename) { rm $filename -Force -ErrorAction SilentlyContinue }
            $doc.SaveAs([ref]$filename, [ref]$file_formatcode)
        } )

        $transactionname = "Word - Print preview"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $doc.PrintPreview()        
            } )

        <#
        $transactionname = "Word - Print"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            # set active printer             
            $word.activeprinter = $printer
            
            # Document afdrukken
            $doc.PrintOut([ref]$false)
            } )
        #>

        $transactionname = "Word - Quit"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            # Close document
            $doc.Close()
            # Exit Word
            $word.Quit()
                } )

    # Start Excel 
        $transactionname = "Excel - start"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $excel = new-object -comobject Excel.Application
            $excel.visible = $True
            } )
    
        # Open workbook
        $transactionname = "Excel - Open testfile"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $wb = $excel.Workbooks.Open($testworkbook)
            } )
    
        # Save workbook
        $transactionname = "Excel - Save testfile"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $filename = "$($env:temp)\test.xlsx"        
            $excel.displayalerts = $false
            $wb.SaveAs($filename)
            } )
    	
    # Close Excel
        $transactionname = "Excel - Quit"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $excel.quit()
        } )

    # Visit AppV Content Store
        $transactionname = "AppV - ContentStore"
        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $app = Start-Process cmd.exe -PassThru -ArgumentList " /k dir `"$($appvcontentstore)`" /ogneds" -WorkingDirectory "C:\" 

            } )
        
            # Content store Sluiten
            Stop-Process -Id $app.Id 

    # AppV Application
    # %ALLUSERSPROFILE%\Microsoft\AppV\Client\Integration\4C39F850-61B3-4ED5-95E0-0F21C0B6D0BB\Root\DLS.exe
        $transactionname = "AppV Application Dymo Label Writer"
        Write-Transaction -transactionname $transactionname -sleepseconds 5 -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
            $app = Start-Process  C:\ProgramData\Microsoft\AppV\Client\Integration\4C39F850-61B3-4ED5-95E0-0F21C0B6D0BB\Root\DLS.exe -PassThru 

            } )
        
            # Content store Sluiten
            Stop-Process -Id $app.Id 

   

    # End of test
        $result = Show-PopUp -Message "Test ended sucessfully" -Title "Test Automation" -ButtonSet OK -IconType Information
}
catch
{
    # log if an error occurs, including a screenshot with the error
    $Error

    Write-Transaction -transactionname "ERROR $transactionname" -sleepseconds 0 -outputfile $outputfile -screenshot $true -measured ( Measure-Command { sleep -Milliseconds 100 } )

    $result = Show-PopUp -Message "Test ended with error" -Title "Test Automation" -ButtonSet OK -IconType Exclamation
}

# Ask for conversion to PDF
    $result = Show-PopUp -Message "Do you want to write the results to a PDF file?" -Title "PDF file" -ButtonSet YNC -IconType Question

    if ($result -eq 6)
    {
        # when in an Citrix Session log some information about Citrix
        $sessioninfo = (Get-ItemProperty -Path HKLM:SOFTWARE\Citrix\ICA\Session -ErrorAction SilentlyContinue )
        $outputpdf = (Get-FileName -defaultFileName "$(get-date ((ls $outputfile).CreationTime) -Format "yyyy-MM-dd HHmmss") Workplace and VDI test-automation with PowerShell.pdf" )        
        $message = "VDI Desktop Image testscript run on $(get-date -Format "yyyy-MM-dd HH:mm"). `n`nOutput PDF: $(split-path $outputpdf -leaf)`nComputername: $($env:computername)`n"
		# when in an Citrix Session log some information about Citrix
		if ($sessioninfo -ne $null)
		{
			$message += "Clientaddress: $($sessioninfo.clientaddress) `nClientname: $($sessioninfo.clientname) `nClientversion: $($sessioninfo.clientversion)"
		}
		$message += "`n`n"
        convert-su-to-pdf -inputsu $outputfile -outputpdf $outputpdf -title "Desktop Image functional Script" -message $message
    }

# ask for logoff
    $result = Show-PopUp -Message "Do you want to logoff?" -Title "Logoff" -ButtonSet YNC -IconType Question

    if ($result -eq 6)
    {
        start-process logoff
    }

Download
Download the script, module and test-files here: sources.zip

Powershell: Process all files in current folders and subfolders

You want to do something with all the files, or a selection of files, in the current folder or subfolder? In a Command Prompt or in VBscript this is a little hassle. In PowerShell is this very easy.

At first start your PowerShell ISE

PowerShell ISE

In this type type the following code:

# collect all files in current folder and subfolders, matching extension .evtx
# to only process the current folder remove the '-Recurse' option
$evtfiles = get-childitem -Filter *.evtx -Recurse
 
foreach ($evtfile in $evtfiles)
{
    # Display the filename including path to the console
    write-host "Scanning" $evtfile.fullname

    # Display only the filename to the console
    write-host "Scanning" $evtfile.name
   
    # command example with wevtutil (Windows Event Viewer Commandline)
    wevtutil qe $evtfile.fullname /lf:true "/q:*[System[(EventID=1085)]]" /f:text   
 
}

So you can quickly process a certain command to all the files you filtered.