From 3bde5ad7dd14c43dde17c6814b5bd8d50cf0c102 Mon Sep 17 00:00:00 2001 From: Sebastian Neumann Date: Sun, 30 Jul 2017 19:42:21 +0200 Subject: [PATCH] Huge module overhaul * Updates function help and logic * Adds functions * Adds data for best practice functions --- CitrixImagingTools/CitrixImagingTools.psm1 | 1 + .../Private/Add-ObjectDetail.ps1 | 167 ++++++++++++++ CitrixImagingTools/Private/Get-LsaSecret.ps1 | 2 +- CitrixImagingTools/Private/Get-OSInfo.ps1 | 13 +- .../Private/Get-Personality.ps1 | 2 +- CitrixImagingTools/Private/Get-PvsPath.ps1 | 6 +- CitrixImagingTools/Private/Get-Tag.ps1 | 37 ++++ CitrixImagingTools/Private/Get-Tag2.ps1 | 37 ++++ .../Private/ScheduledTasks-2016.csv | 24 +++ .../Private/ScheduledTasks-Win10.csv | 31 +++ CitrixImagingTools/Private/Set-LsaSecret.ps1 | 2 +- .../Private/Start-ConsoleProcess.ps1 | 203 ++++++++++++++++++ .../Public/Add-AutoAdminLogon.ps1 | 3 +- .../Public/Clear-EventLogFull.ps1 | 3 +- .../Public/Clear-NetworkCache.ps1 | 3 +- .../Disable-ADComputerPasswordChange.ps1 | 10 +- .../Public/Disable-BackgroundAutoLayout.ps1 | 35 +++ .../Disable-BackgroundDefragmentation.ps1 | 35 +++ .../Disable-ClearPageFileAtShutdown.ps1 | 20 +- .../Public/Disable-Hibernation.ps1 | 26 +++ .../Public/Disable-LargeSendOffloading.ps1 | 16 +- .../Public/Disable-LastAccessTimestamp.ps1 | 21 ++ .../Public/Disable-OfflineFiles.ps1 | 9 +- .../Public/Disable-Superfetch.ps1 | 33 +++ .../Public/Disable-SystrayIcon.ps1 | 21 +- .../Public/Disable-TcpTaskOffloading.ps1 | 22 +- .../Public/Disable-WindowsUpdate.ps1 | 16 +- .../Enable-HighPerformancePowerScheme.ps1 | 25 +++ ...le-TargetDeviceGetComputerNameFallback.ps1 | 36 ++++ .../Public/Get-AutoAdminLogon.ps1 | 3 +- .../Get-DataExecutionPreventionStatus.ps1 | 89 ++++++++ .../Public/Get-OperatingSystemFamily.ps1 | 2 +- .../Public/Get-ProvisioningType.ps1 | 29 +-- CitrixImagingTools/Public/Get-PvsRamCache.ps1 | 6 +- .../Public/Get-WindowsEnvironmentVariable.ps1 | 3 +- CitrixImagingTools/Public/Import-IniFile.ps1 | 2 +- CitrixImagingTools/Public/Invoke-Robocopy.ps1 | 156 ++++++++++++++ CitrixImagingTools/Public/Move-EventLog.ps1 | 3 +- .../Public/Optimize-GlobalAssemblyCache.ps1 | 32 +++ CitrixImagingTools/Public/Optimize-SMBv2.ps1 | 56 +++++ .../Public/Optimize-WindowsUpdate.ps1 | 3 +- .../Public/Remove-CommonAutostart.ps1 | 5 +- .../Public/Remove-CommonDesktopShortcut.ps1 | 3 +- CitrixImagingTools/Public/Remove-FloppyCD.ps1 | 3 +- .../Public/Set-DiskIOTimeout.ps1 | 44 ++++ .../Public/Set-ServiceStartupTimeout.ps1 | 52 +++++ CitrixImagingTools/Public/Set-Shortcut.ps1 | 15 +- .../Public/Set-SpoolerDirectory.ps1 | 13 +- CitrixImagingTools/Public/Set-TSLogonMode.ps1 | 14 +- .../Public/Set-UniqueDiskID.ps1 | 3 +- .../Public/Show-ProgressBar.ps1 | 14 +- .../Public/Start-Defragmentation.ps1 | 21 +- CitrixImagingTools/Public/Start-P2PVS.ps1 | 16 +- .../{WIP => Public}/Start-SealImage.ps1 | 62 ++++-- CitrixImagingTools/WIP/OptimizationSteps.ps1 | 21 ++ 55 files changed, 1391 insertions(+), 138 deletions(-) create mode 100644 CitrixImagingTools/Private/Add-ObjectDetail.ps1 create mode 100644 CitrixImagingTools/Private/Get-Tag.ps1 create mode 100644 CitrixImagingTools/Private/Get-Tag2.ps1 create mode 100644 CitrixImagingTools/Private/Start-ConsoleProcess.ps1 create mode 100644 CitrixImagingTools/Public/Disable-BackgroundAutoLayout.ps1 create mode 100644 CitrixImagingTools/Public/Disable-BackgroundDefragmentation.ps1 create mode 100644 CitrixImagingTools/Public/Disable-Hibernation.ps1 create mode 100644 CitrixImagingTools/Public/Disable-LastAccessTimestamp.ps1 create mode 100644 CitrixImagingTools/Public/Disable-Superfetch.ps1 create mode 100644 CitrixImagingTools/Public/Enable-HighPerformancePowerScheme.ps1 create mode 100644 CitrixImagingTools/Public/Enable-TargetDeviceGetComputerNameFallback.ps1 create mode 100644 CitrixImagingTools/Public/Get-DataExecutionPreventionStatus.ps1 create mode 100644 CitrixImagingTools/Public/Invoke-Robocopy.ps1 create mode 100644 CitrixImagingTools/Public/Optimize-GlobalAssemblyCache.ps1 create mode 100644 CitrixImagingTools/Public/Optimize-SMBv2.ps1 create mode 100644 CitrixImagingTools/Public/Set-DiskIOTimeout.ps1 create mode 100644 CitrixImagingTools/Public/Set-ServiceStartupTimeout.ps1 rename CitrixImagingTools/{WIP => Public}/Start-SealImage.ps1 (68%) diff --git a/CitrixImagingTools/CitrixImagingTools.psm1 b/CitrixImagingTools/CitrixImagingTools.psm1 index 09e1818..32cfd35 100644 --- a/CitrixImagingTools/CitrixImagingTools.psm1 +++ b/CitrixImagingTools/CitrixImagingTools.psm1 @@ -19,3 +19,4 @@ Foreach ($import in @($Public + $Private)) Export-ModuleMember -Function $Public.Basename Add-Type -Path "$PSScriptRoot\Private\LsaSecretsHelper.cs" +#Update-TypeData -TypeName System.Management.Automation.CmdletInfo -MemberName Tags -MemberType Scriptproperty -Value {Get-Tag2 -InputObject $this.Definition} diff --git a/CitrixImagingTools/Private/Add-ObjectDetail.ps1 b/CitrixImagingTools/Private/Add-ObjectDetail.ps1 new file mode 100644 index 0000000..6ddbc26 --- /dev/null +++ b/CitrixImagingTools/Private/Add-ObjectDetail.ps1 @@ -0,0 +1,167 @@ +function Add-ObjectDetail +{ + <# + .SYNOPSIS + Decorate an object with + - A TypeName + - New properties + - Default parameters + + .DESCRIPTION + Helper function to decorate an object with + - A TypeName + - New properties + - Default parameters + + .PARAMETER InputObject + Object to decorate. Accepts pipeline input. + + .PARAMETER TypeName + Typename to insert. + + This will show up when you use Get-Member against the resulting object. + + .PARAMETER PropertyToAdd + Add these noteproperties. + + Format is a hashtable with Key (Property Name) = Value (Property Value). + + Example to add a One and Date property: + + -PropertyToAdd @{ + One = 1 + Date = (Get-Date) + } + + .PARAMETER DefaultProperties + Change the default properties that show up + + .PARAMETER Passthru + Whether to pass the resulting object on. Defaults to true + + .EXAMPLE + # + # Create an object to work with + $Object = [PSCustomObject]@{ + First = 'Cookie' + Last = 'Monster' + Account = 'CMonster' + } + + #Add a type name and a random property + Add-ObjectDetail -InputObject $Object -TypeName 'ApplicationX.Account' -PropertyToAdd @{ AnotherProperty = 5 } + + # First Last Account AnotherProperty + # ----- ---- ------- --------------- + # Cookie Monster CMonster 5 + + #Verify that get-member shows us the right type + $Object | Get-Member + + # TypeName: ApplicationX.Account ... + + .EXAMPLE + # + # Create an object to work with + $Object = [PSCustomObject]@{ + First = 'Cookie' + Last = 'Monster' + Account = 'CMonster' + } + + #Add a random property, set a default property set so we only see two props by default + Add-ObjectDetail -InputObject $Object -PropertyToAdd @{ AnotherProperty = 5 } -DefaultProperties Account, AnotherProperty + + # Account AnotherProperty + # ------- --------------- + # CMonster 5 + + #Verify that the other properties are around + $Object | Select -Property * + + # First Last Account AnotherProperty + # ----- ---- ------- --------------- + # Cookie Monster CMonster 5 + + .NOTES + This breaks the 'do one thing' rule from certain perspectives... + The goal is to decorate an object all in one shot + + This abstraction simplifies decorating an object, with a slight trade-off in performance. For example: + + 10,000 objects, add a property and typename: + Add-ObjectDetail: ~4.6 seconds + Add-Member + PSObject.TypeNames.Insert: ~3 seconds + + Initial code borrowed from Shay Levy: + http://blogs.microsoft.co.il/scriptfanatic/2012/04/13/custom-objects-default-display-in-powershell-30/ + + .FUNCTIONALITY + PowerShell Language + #> + [CmdletBinding()] + param( + [Parameter( Mandatory = $true, + Position=0, + ValueFromPipeline=$true )] + [ValidateNotNullOrEmpty()] + [psobject[]]$InputObject, + + [Parameter( Mandatory = $false, + Position=1)] + [string]$TypeName, + + [Parameter( Mandatory = $false, + Position=2)] + [System.Collections.Hashtable]$PropertyToAdd, + + [Parameter( Mandatory = $false, + Position=3)] + [ValidateNotNullOrEmpty()] + [Alias('dp')] + [System.String[]]$DefaultProperties, + + [boolean]$Passthru = $True + ) + + Begin + { + if($PSBoundParameters.ContainsKey('DefaultProperties')) + { + # define a subset of properties + $ddps = New-Object System.Management.Automation.PSPropertySet DefaultDisplayPropertySet,$DefaultProperties + $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]$ddps + } + } + Process + { + foreach($Object in $InputObject) + { + switch ($PSBoundParameters.Keys) + { + 'PropertyToAdd' + { + foreach($Key in $PropertyToAdd.Keys) + { + #Add some noteproperties. Slightly faster than Add-Member. + $Object.PSObject.Properties.Add( ( New-Object System.Management.Automation.PSNoteProperty($Key, $PropertyToAdd[$Key]) ) ) + } + } + 'TypeName' + { + #Add specified type + [void]$Object.PSObject.TypeNames.Insert(0,$TypeName) + } + 'DefaultProperties' + { + # Attach default display property set + Add-Member -InputObject $Object -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers + } + } + if($Passthru) + { + $Object + } + } + } +} diff --git a/CitrixImagingTools/Private/Get-LsaSecret.ps1 b/CitrixImagingTools/Private/Get-LsaSecret.ps1 index 54ed71b..98f5cc2 100644 --- a/CitrixImagingTools/Private/Get-LsaSecret.ps1 +++ b/CitrixImagingTools/Private/Get-LsaSecret.ps1 @@ -25,7 +25,7 @@ function Get-LsaSecret $UnsecureString = [PSCredential]::New("user",$Secret.Value).GetNetworkCredential().Password .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] diff --git a/CitrixImagingTools/Private/Get-OSInfo.ps1 b/CitrixImagingTools/Private/Get-OSInfo.ps1 index ff504f3..c2fa648 100644 --- a/CitrixImagingTools/Private/Get-OSInfo.ps1 +++ b/CitrixImagingTools/Private/Get-OSInfo.ps1 @@ -5,14 +5,17 @@ function Get-OSInfo $NICInfo = Get-CimInstance -ClassName win32_networkadapterconfiguration -Filter "DHCPEnabled='True' and DNSHostName='$env:COMPUTERNAME'" [pscustomobject]@{ - PSVersion = $PSVersionTable.PSVersion - Domain = $ComputerSystemInfo.Domain - PartOfDomain = $ComputerSystemInfo.PartOfDomain - NICs = $NICInfo - Drives = [pscustomobject]@{ + PSVersion = $PSVersionTable.PSVersion + Domain = $ComputerSystemInfo.Domain + PartOfDomain = $ComputerSystemInfo.PartOfDomain + NICs = $NICInfo + NumCPU = $ComputerSystemInfo.NumberOfProcessors + NumCPULogical = $ComputerSystemInfo.NumberOfLogicalProcessors + Drives = [pscustomobject]@{ Disks = $DriveInfo | Where-Object DriveType -eq 3 CD = $DriveInfo | Where-Object DriveType -eq 5 Floppy = $DriveInfo | Where-Object DriveType -eq 2 } + } } diff --git a/CitrixImagingTools/Private/Get-Personality.ps1 b/CitrixImagingTools/Private/Get-Personality.ps1 index a04f46e..680b8d6 100644 --- a/CitrixImagingTools/Private/Get-Personality.ps1 +++ b/CitrixImagingTools/Private/Get-Personality.ps1 @@ -2,5 +2,5 @@ function Get-Personality { $PersonalityIni = Get-Item -LiteralPath "$env:SystemDrive\Personality.ini" -ErrorAction Stop - Import-IniFile -FilePath $PersonalityIni.FullName + CitriImagingTools\Import-IniFile -FilePath $PersonalityIni.FullName } diff --git a/CitrixImagingTools/Private/Get-PvsPath.ps1 b/CitrixImagingTools/Private/Get-PvsPath.ps1 index abb1e14..a42c77c 100644 --- a/CitrixImagingTools/Private/Get-PvsPath.ps1 +++ b/CitrixImagingTools/Private/Get-PvsPath.ps1 @@ -9,14 +9,14 @@ Function Get-PvsPath #> try { - if (Test-Path -LiteraPath "$env:ProgramFiles\Citrix\Provisioning Services") + if (Test-Path -LiteralPath "$env:ProgramFiles\Citrix\Provisioning Services") { - $Path = Get-Item -LiteraPath "$env:ProgramFiles\Citrix\Provisioning Services" + $Path = Get-Item -LiteralPath "$env:ProgramFiles\Citrix\Provisioning Services" } else { $Pkg = Get-Package -Name 'Citrix Provisioning Services Target Device x64' - $Path = Get-Item -LiteraPath $Pkg.FullPath + $Path = Get-Item -LiteralPath $Pkg.FullPath } return $Path diff --git a/CitrixImagingTools/Private/Get-Tag.ps1 b/CitrixImagingTools/Private/Get-Tag.ps1 new file mode 100644 index 0000000..ec04f1f --- /dev/null +++ b/CitrixImagingTools/Private/Get-Tag.ps1 @@ -0,0 +1,37 @@ +function Get-Tag +{ + [CmdletBinding(DefaultParameterSetName='String')] + param( + [Parameter(ParameterSetName='Path',ValueFromPipeline=$true)] + $Path, + + [Parameter(ParameterSetName='String',ValueFromPipeline=$true)] + $InputObject + ) + + Begin + { + $TagsPattern = ([regex]'(?m)^[\s]{0,15}Tags:(?.*)$') + } + + Process + { + foreach ($P in $Path) + { + $Result = Select-String -Pattern $TagsPattern -Path $P + $TagList = $Result.Matches | Foreach-Object { + $Tags = $_.Groups['Tags'].Value + + if (-not [string]::IsNullOrEmpty($Tags)) + { + $Tags.Trim().Split(',') + } + } + + [pscustomobject]@{ + Path = $P + Tags = $TagList + } + } + } +} diff --git a/CitrixImagingTools/Private/Get-Tag2.ps1 b/CitrixImagingTools/Private/Get-Tag2.ps1 new file mode 100644 index 0000000..8addf09 --- /dev/null +++ b/CitrixImagingTools/Private/Get-Tag2.ps1 @@ -0,0 +1,37 @@ +function Get-Tag2 +{ + [CmdletBinding()] + param( + $InputObject + ) + + Begin + { + $TagsPattern = ([regex]'(?m)^[\s]{0,15}Tags:(?.*)$') + } + + Process + { + foreach ($I in $InputObject) + { + $Result = Select-String -Pattern $TagsPattern -InputObject $I + $TagList = $Result.Matches | Foreach-Object { + try + { + $Tags = $_.Groups['Tags'].Value + + if (-not [string]::IsNullOrEmpty($Tags)) + { + $Tags.Trim().Split(',') + } + } + catch + { + $null + } + } + + $TagList + } + } +} diff --git a/CitrixImagingTools/Private/ScheduledTasks-2016.csv b/CitrixImagingTools/Private/ScheduledTasks-2016.csv index e69de29..1253d44 100644 --- a/CitrixImagingTools/Private/ScheduledTasks-2016.csv +++ b/CitrixImagingTools/Private/ScheduledTasks-2016.csv @@ -0,0 +1,24 @@ +Tasks;Category;Description +AutoCHK\Proxy;CEIP;This task collects and uploads autochk SQM data if opted-in to the Microsoft Customer Experience Improvement Program. +Customer Experience Improvement Program \Consolidator;CEIP;If the user has consented to participate in the Windows Customer Experience Improvement Program, this job collects and sends usage data to Microsoft. +Customer Experience Improvement Program \KernelCeipTask;CEIP;The Kernel CEIP (Customer Experience Improvement Program) task collects additional information about the system and sends this data to Microsoft. If the user has not consented to participate in Windows CEIP, this task does nothing. +Customer Experience Improvement Program \Uploader;CEIP;This job sends data about windows based on user participation in the Windows Customer Experience Improvement Program +Customer Experience Improvement Program \UsbCeip;CEIP;The USB CEIP (Customer Experience Improvement Program) task collects Universal Serial Bus related statistics and information about your machine and sends to the Windows Device Connectivity engineering group at Microsoft. The information received is used to help improve the reliability, stability, and overall functionality of USB in Windows. If the user has not consented to participate in Windows CEIP, this task does not do anything. +Application Experience\Microsoft Compatibility Appraiser;Applications;Helps resolve application compatibility challenges. +Application Experience\StartupTask;Applications;Determines if there are too many startup entries and then notifies the user +Windows Defender\Windows Defender Cache Maintenance;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Defender\Windows Defender Cleanup;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Defender\Windows Defender Scheduled Scan;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Defender\Windows Defender Verification;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Filtering Platform \BfeOnServiceStartTypeChange;Safety;This task adjusts the start type for firewall-triggered services when the start type of the Base Filtering Engine (BFE) is disabled. +CHKDSK\Proactive Scan;Maintenance;NTFS Volume Health Scan +Diagnosis\Scheduled;Maintenance;The Windows Scheduled Maintenance Task performs periodic maintenance of the computer system by fixing problems automatically or reporting them through the Action Center. +DiskDiagnostic\Microsoft-Windows-DiskDiagnosticDataCollector;Maintenance;The Windows Disk Diagnostic reports general disk and system information to Microsoft for users participating in the Customer Experience Program. +Maintenance\WinSAT;Maintenance;Measures a system�s performance and capabilities +Power Efficiency Diagnostics\AnalyzeSystem;Maintenance;This task analyzes the system looking for conditions that may cause high energy use. +RecoveryEnvironment\VerifyWinRE;Maintenance;Validates the Windows Recovery Environment. +Registry\RegIdleBackup;Maintenance;Registry Idle Backup Task +Mobile Broadband Accounts / MNO Metadata Parser;General;Parses information related to mobile broadband users +RAS / MobilityManager;General;Provides support for the switching of mobility enabled VPN connections if their underlying interface goes down. +Shell / IndexerAutomaticMaintenance;General;Maintains the search index +WDI\ResolutionHost;General;The Windows Diagnostic Infrastructure Resolution host enables interactive resolutions for system problems detected by the Diagnostic Policy Service. It is triggered when necessary by the Diagnostic Policy Service in the appropriate user session. If the Diagnostic Policy Service is not running, the task will not run. diff --git a/CitrixImagingTools/Private/ScheduledTasks-Win10.csv b/CitrixImagingTools/Private/ScheduledTasks-Win10.csv index e69de29..e7d3be9 100644 --- a/CitrixImagingTools/Private/ScheduledTasks-Win10.csv +++ b/CitrixImagingTools/Private/ScheduledTasks-Win10.csv @@ -0,0 +1,31 @@ +Tasks;Category;Description +Application Experience\Appraiser;CEIP;Aggregates and uploads Application Telemetry information if opted-in to the Microsoft Customer Experience Improvement Program. +Application Experience\ProgramDataUpdater;CEIP;Collects program telemetry information if opted-in to the Microsoft Customer Experience Improvement Program +AutoCHK\Proxy;CEIP;This task collects and uploads autochk SQM data if opted-in to the Microsoft Customer Experience Improvement Program. +Customer Experience Improvement Program \Consolidator;CEIP;If the user has consented to participate in the Windows Customer Experience Improvement Program, this job collects and sends usage data to Microsoft. +Customer Experience Improvement Program \KernelCeipTask;CEIP;The Kernel CEIP (Customer Experience Improvement Program) task collects additional information about the system and sends this data to Microsoft. If the user has not consented to participate in Windows CEIP, this task does nothing. +Customer Experience Improvement Program \Uploader;CEIP;This job sends data about windows based on user participation in the Windows Customer Experience Improvement Program +Customer Experience Improvement Program \UsbCeip;CEIP;The USB CEIP (Customer Experience Improvement Program) task collects Universal Serial Bus related statistics and information about your machine and sends to the Windows Device Connectivity engineering group at Microsoft. The information received is used to help improve the reliability, stability, and overall functionality of USB in Windows. If the user has not consented to participate in Windows CEIP, this task does not do anything. +Shell\FamilySafetyMonitor;Safety;Initializes Family Safety monitoring and enforcement. +Shell\FamilySafetyRefresh;Safety;Synchronizes the latest settings with the Family Safety website. +Windows Defender\Windows Defender CacheMaintenance;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Defender\Windows Defender CacheMaintenance;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Defender\Windows Defender Cleanup;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Defender\Windows DefenderScheduled Scan;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Defender\Windows DefenderVerification;Safety;Can be disabled in case an alternative virus and malware protection has been implemented. +Windows Filtering Platform \BfeOnServiceStartTypeChange;Safety;This task adjusts the start type for firewall-triggered services when the start type of the Base Filtering Engine (BFE) is disabled. +Application Experience\StartupAppTask;Optimization;Scans startup entries and raises notification to the user if there are too many startup entries. +CHKDSK\Proactive Scan;Optimization;NTFS Volume Health Scan +Diagnosis\Scheduled;Optimization;The Windows Scheduled Maintenance Task performs periodic maintenance of the computer system by fixing problems automatically or reporting them through the Action Center. +DiskDiagnostic\Microsoft-Windows-DiskDiagnosticDataCollector;Optimization;The Windows Disk Diagnostic reports general disk and system information to Microsoft for users participating in the Customer Experience Program. +DiskDiagnostic\Microsoft-Windows-DiskDiagnosticResolver;Optimization;This task warns users about faults that occur on disks that support Self-Monitoring and Reporting Technology +Defrag\ScheduledDefrag;Optimization;This task optimizes local storage drives +FileHistory\File History;Optimization;Protects user files from accidental loss by copying them to a backup location when the system is unattended +Maintenance\WinSAT;Optimization;Measures a systems performance and capabilities +MemoryDiagnostic\ProcessMemoryDiagnosticEvents;Optimization;Schedules a memory diagnostic in response to system events. +MemoryDiagnostic\RunFullMemoryDiagnostic;Optimization;Detects and mitigates problems in physical memory (RAM). +Power Efficiency Diagnostics\AnalyzeSystem;Optimization;This task analyzes the system looking for conditions that may cause high energy use. +RecoveryEnvironment\VerifyWinRE;Optimization;Validates the Windows Recovery Environment. +Registry\RegIdleBackup;Optimization;Registry Idle Backup Task +SystemRestore\SR;Optimization;This task creates regular system protection points. +WDI\ResolutionHost;Optimization;The Windows Diagnostic Infrastructure Resolution host enables interactive resolutions for system problems detected by the Diagnostic Policy Service. It is triggered when necessary by the Diagnostic Policy Service in the appropriate user session. If the Diagnostic Policy Service is not running, the task will not run diff --git a/CitrixImagingTools/Private/Set-LsaSecret.ps1 b/CitrixImagingTools/Private/Set-LsaSecret.ps1 index a50e455..86bec72 100644 --- a/CitrixImagingTools/Private/Set-LsaSecret.ps1 +++ b/CitrixImagingTools/Private/Set-LsaSecret.ps1 @@ -18,7 +18,7 @@ function Set-LsaSecret Set-LsaSecret -Key MyKey -Value $ValueAsSecureString .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) #> [CmdletBinding(SupportsShouldProcess = $true)] diff --git a/CitrixImagingTools/Private/Start-ConsoleProcess.ps1 b/CitrixImagingTools/Private/Start-ConsoleProcess.ps1 new file mode 100644 index 0000000..c27681b --- /dev/null +++ b/CitrixImagingTools/Private/Start-ConsoleProcess.ps1 @@ -0,0 +1,203 @@ +function Start-ConsoleProcess +{ + <# + .Synopsis + Launch console process, pipe strings to its StandardInput + and get resulting StandardOutput/StandardError streams and exit code. + + .Description + This function will start console executable, pipe any user-specified strings to it + and capture StandardOutput/StandardError streams and exit code. + It returns object with following properties: + + StdOut - array of strings captured from StandardOutput + StdErr - array of strings captured from StandardError + ExitCode - exit code set by executable + + .Parameter FilePath + Path to the executable or its name. + + .Parameter ArgumentList + Array of arguments for the executable. + Passing arguments as an array allows to run even such unfriendly applications as robocopy. + + .Parameter InputObject + Array of strings to be piped to the executable's StandardInput. + This allows you to execute commands in interactive sessions of netsh and diskpart. + + .Notes + Tags: + + .Example + Start-ConsoleProcess -FilePath find + + Start find.exe and capture its output. + Because no arguments specified, find.exe prints error to StandardError stream, + which is captured by the function: + + StdOut StdErr ExitCode + ------ ------ -------- + {} {FIND: Parameter format not correct} 2 + + .Example + 'aaa', 'bbb', 'ccc' | Start-ConsoleProcess -FilePath find -ArgumentList '"aaa"' + + Start find.exe, pipe strings to its StandardInput and capture its output. + Find.exe will attempt to find string "aaa" in StandardInput stream and + print matches to StandardOutput stream, which is captured by the function: + + StdOut StdErr ExitCode + ------ ------ -------- + {aaa} {} 0 + + .Example + 'list disk', 'list volume' | Start-ConsoleProcess -FilePath diskpart + + Start diskpart.exe, pipe string to its StandardInput and capture its output. + Diskpart.exe will accept piped strings as if they were typed in the interactive session + and list all disks and volumes on the PC. + + Note that running diskpart requires already elevated PowerShell console. + Otherwise, you will recieve elevation request and diskpart will run, + however, no strings would be piped to it. + + Example: + + PS > $Result = 'list disk', 'list volume' | Start-ConsoleProcess -FilePath diskpart + PS > $Result.StdOut + + Microsoft DiskPart version 6.3.9600 + + Copyright (C) 1999-2013 Microsoft Corporation. + On computer: HAL9000 + + DISKPART> + Disk ### Status Size Free Dyn Gpt + -------- ------------- ------- ------- --- --- + Disk 0 Online 298 GB 0 B + + DISKPART> + Volume ### Ltr Label Fs Type Size Status Info + ---------- --- ----------- ----- ---------- ------- --------- -------- + Volume 0 E DVD-ROM 0 B No Media + Volume 1 C System NTFS Partition 100 GB Healthy System + Volume 2 D Storage NTFS Partition 198 GB Healthy + + DISKPART> + + .Example + Start-ConsoleProcess -FilePath robocopy -ArgumentList 'C:\Src', 'C:\Dst', '/mir' + + Start robocopy.exe with arguments and capture its output. + Robocopy.exe will mirror contents of the 'C:\Src' folder to 'C:\Dst' + and print log to StandardOutput stream, which is captured by the function. + + Example: + + PS > $Result = Start-ConsoleProcess -FilePath robocopy -ArgumentList 'C:\Src', 'C:\Dst', '/mir' + PS > $Result.StdOut + + ------------------------------------------------------------------------------- + ROBOCOPY :: Robust File Copy for Windows + ------------------------------------------------------------------------------- + + Started : 01 January 2016 y. 00:00:01 + Source : C:\Src\ + Dest : C:\Dst\ + + Files : *.* + + Options : *.* /S /E /DCOPY:DA /COPY:DAT /PURGE /MIR /R:1000000 /W:30 + + ------------------------------------------------------------------------------ + + 1 C:\Src\ + New File 6 Readme.txt + 0% + 100% + + ------------------------------------------------------------------------------ + + Total Copied Skipped Mismatch FAILED Extras + Dirs : 1 0 0 0 0 0 + Files : 1 1 0 0 0 0 + Bytes : 6 6 0 0 0 0 + Times : 0:00:00 0:00:00 0:00:00 0:00:00 + + + Speed : 103 Bytes/sec. + Speed : 0.005 MegaBytes/min. + Ended : 01 January 2016 y. 00:00:01 + #> + + Param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$FilePath, + + [string[]]$ArgumentList, + + [Parameter(ValueFromPipeline = $true)] + [string[]]$InputObject + ) + + End + { + if($Input) + { + # Collect all pipeline input + # http://www.powertheshell.com/input_psv3/ + $StdIn = @($Input) + } + else + { + $StdIn = $InputObject + } + + try + { + "Starting process: $FilePath", "Redirect StdIn: $([bool]$StdIn.Count)", "Arguments: $ArgumentList" | Write-Verbose + + if($StdIn.Count) + { + $Output = $StdIn | & $FilePath $ArgumentList 2>&1 + } + else + { + $Output = & $FilePath $ArgumentList 2>&1 + } + } + catch + { + throw $_ + } + + Write-Verbose 'Finished, processing output' + + $StdOut = New-Object -TypeName System.Collections.Generic.List``1[String] + $StdErr = New-Object -TypeName System.Collections.Generic.List``1[String] + + foreach($item in $Output) + { + # Data from StdOut will be strings, while StdErr produces + # System.Management.Automation.ErrorRecord objects. + # http://stackoverflow.com/a/33002914/4424236 + if($item.Exception.Message) + { + $StdErr.Add($item.Exception.Message) + } + else + { + $StdOut.Add($item) + } + } + + Write-Verbose 'Returning result' + New-Object -TypeName PSCustomObject -Property @{ + ExitCode = $LASTEXITCODE + StdOut = $StdOut.ToArray() + StdErr = $StdErr.ToArray() + } | Select-Object -Property StdOut, StdErr, ExitCode + } +} diff --git a/CitrixImagingTools/Public/Add-AutoAdminLogon.ps1 b/CitrixImagingTools/Public/Add-AutoAdminLogon.ps1 index 63b0acc..2116c9d 100644 --- a/CitrixImagingTools/Public/Add-AutoAdminLogon.ps1 +++ b/CitrixImagingTools/Public/Add-AutoAdminLogon.ps1 @@ -47,7 +47,8 @@ switch was not provided. .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Credential, Account #> [Cmdletbinding(SupportsShouldProcess = $true)] diff --git a/CitrixImagingTools/Public/Clear-EventLogFull.ps1 b/CitrixImagingTools/Public/Clear-EventLogFull.ps1 index 93af20a..07cbdae 100644 --- a/CitrixImagingTools/Public/Clear-EventLogFull.ps1 +++ b/CitrixImagingTools/Public/Clear-EventLogFull.ps1 @@ -12,7 +12,8 @@ function Clear-EventLogFull Clear-EventLogFull .NOTES - ToDo: Add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Sealing #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param() diff --git a/CitrixImagingTools/Public/Clear-NetworkCache.ps1 b/CitrixImagingTools/Public/Clear-NetworkCache.ps1 index 7042e23..c26c6b3 100644 --- a/CitrixImagingTools/Public/Clear-NetworkCache.ps1 +++ b/CitrixImagingTools/Public/Clear-NetworkCache.ps1 @@ -11,7 +11,8 @@ function Clear-NetworkCache Clear-NetworkCache .NOTES - ToDo: Add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Network, Sealing #> ipconfig.exe /flushdns diff --git a/CitrixImagingTools/Public/Disable-ADComputerPasswordChange.ps1 b/CitrixImagingTools/Public/Disable-ADComputerPasswordChange.ps1 index 5dfaac9..7025b02 100644 --- a/CitrixImagingTools/Public/Disable-ADComputerPasswordChange.ps1 +++ b/CitrixImagingTools/Public/Disable-ADComputerPasswordChange.ps1 @@ -5,15 +5,17 @@ function Disable-ADComputerPasswordChange Disables periodic AD computer password changes. .DESCRIPTION - This is required for PVS target devices since. PVS takes + This is required for PVS target devices since PVS takes care of changing the passwords in AD every 7 days by default. .EXAMPLE Disable-ADComputerPasswordChange ToDO: Add examples + .NOTES - ToDo: Add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] @@ -26,8 +28,8 @@ function Disable-ADComputerPasswordChange Value = 1 } - if ($PSCmdlet.ShouldProcess('Disable periodic Computer password changes')) + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable periodic Computer password changes')) { - New-ItemProperty @Params -Force + New-ItemProperty @Params -Force | Out-Null } } diff --git a/CitrixImagingTools/Public/Disable-BackgroundAutoLayout.ps1 b/CitrixImagingTools/Public/Disable-BackgroundAutoLayout.ps1 new file mode 100644 index 0000000..9775a0b --- /dev/null +++ b/CitrixImagingTools/Public/Disable-BackgroundAutoLayout.ps1 @@ -0,0 +1,35 @@ +Function Disable-BackgroundAutoLayout +{ + <# + .SYNOPSIS + Disables background auto-layout service. + + .DESCRIPTION + The auto-layout service moves the most-used data closer to the center of the + disk to expedite boot time. This service, if enabled, can cause unnecessary + writes to the cache of non-persistent machines. + + .EXAMPLE + Disable-BackgroundAutoLayout + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build, Filesystem + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + $Params = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\OptimalLayout' + Name = 'EnableAutoLayout' + PropertyType = 'Dword' + Value = 0 + } + + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable background auto-layout service')) + { + New-ItemProperty @Params -Force | Out-Null + } +} + diff --git a/CitrixImagingTools/Public/Disable-BackgroundDefragmentation.ps1 b/CitrixImagingTools/Public/Disable-BackgroundDefragmentation.ps1 new file mode 100644 index 0000000..c261922 --- /dev/null +++ b/CitrixImagingTools/Public/Disable-BackgroundDefragmentation.ps1 @@ -0,0 +1,35 @@ +Function Disable-BackgroundDefragmentation +{ + <# + .SYNOPSIS + Disables Disk Defragmentation BootOptimizeFunction. + + .DESCRIPTION + Not required for MCS or PVS based nonpersistent virtual desktops. + File system changes are discarded after reboot. + + Disabling Automatic Disk Defragmentation prevents Window from filling the + vDisk write cache by automatically defragmenting the vDisk during boot time. + + .EXAMPLE + Disable-BackgroundDefragmentation + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Filesystem, Build + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + $Params = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Dfrg\BootOptimizeFunction' + Name = 'Enable' + Value = 'N' + } + + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable on-boot disk defragmentation')) + { + New-ItemProperty @Params -Force | Out-Null + } +} diff --git a/CitrixImagingTools/Public/Disable-ClearPageFileAtShutdown.ps1 b/CitrixImagingTools/Public/Disable-ClearPageFileAtShutdown.ps1 index 22bbc58..b871e09 100644 --- a/CitrixImagingTools/Public/Disable-ClearPageFileAtShutdown.ps1 +++ b/CitrixImagingTools/Public/Disable-ClearPageFileAtShutdown.ps1 @@ -2,24 +2,18 @@ { <# .SYNOPSIS - ToDo: Disables Offline Files which is recommended for always-on systems. + Disables clearing the paging file during the shutdown process. .DESCRIPTION - ToDo: The disabling of Offline Files is strongly recommended to prevent Windows from caching - network files on its local disk – a feature with no benefit to a diskless system. - - Offline Files saves a copy of network files on the user's computer for use when the computer - is not connected to the network. - - Note: Changes to this setting do not take effect until the affected computer is restarted. + Not required for MCS or PVS based nonpersistent virtual desktops. + Clearing the page file increases shutdown times. .EXAMPLE Disable-ClearPageFileAtShutdown - ToDo: add example output - .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: #> [CmdletBinding(SupportsShouldProcess = $true)] @@ -32,8 +26,8 @@ Value = 0 } - if ($PSCmdlet.ShouldProcess('Disable Clear Page File at Shutdown')) + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable Clear Page File at Shutdown')) { - Set-ItemProperty @Params -Force + New-ItemProperty @Params -Force | Out-Null } } diff --git a/CitrixImagingTools/Public/Disable-Hibernation.ps1 b/CitrixImagingTools/Public/Disable-Hibernation.ps1 new file mode 100644 index 0000000..e038f42 --- /dev/null +++ b/CitrixImagingTools/Public/Disable-Hibernation.ps1 @@ -0,0 +1,26 @@ +function Disable-Hibernation +{ + <# + .SYNOPSIS + Disables hibernation. + + .DESCRIPTION + It's a general best practice to disable hibernation for + virtual desktops and servers. + + .EXAMPLE + Disable-Hibernation -Verbose + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable Hibernation')) + { + & powercfg.exe -HIBERNATE OFF + } +} diff --git a/CitrixImagingTools/Public/Disable-LargeSendOffloading.ps1 b/CitrixImagingTools/Public/Disable-LargeSendOffloading.ps1 index 0142d4d..9494662 100644 --- a/CitrixImagingTools/Public/Disable-LargeSendOffloading.ps1 +++ b/CitrixImagingTools/Public/Disable-LargeSendOffloading.ps1 @@ -1,4 +1,13 @@ -function Disable-LargeSendOffloading +<# +Remove file: +Target Device +Note: For Provisioning Server 6.0 and beyond, BNNS driver is no longer used for Windows 7 and 2008, so this registry key is not applicable. However, BNNS is still used for windows XP and 2003. +HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BNNS\Parameters\ +DWORD = EnableOffload +Value: "0" +#> + +function Disable-LargeSendOffloading { <# .SYNOPSIS @@ -19,7 +28,8 @@ ToDo: add example output .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Network, Build #> [CmdletBinding(SupportsShouldProcess = $true)] @@ -34,6 +44,6 @@ if ($PSCmdlet.ShouldProcess('Disable Large Send Offload on the machine')) { - New-ItemProperty @Params -Force + New-ItemProperty @Params -Force | Out-Null } } diff --git a/CitrixImagingTools/Public/Disable-LastAccessTimestamp.ps1 b/CitrixImagingTools/Public/Disable-LastAccessTimestamp.ps1 new file mode 100644 index 0000000..ae388b4 --- /dev/null +++ b/CitrixImagingTools/Public/Disable-LastAccessTimestamp.ps1 @@ -0,0 +1,21 @@ +Function Disable-LastAccessTimestamp +{ + <# + .SYNOPSIS + Disables the filesystem last access timestamps. + .DESCRIPTION + Disabling the last access timestamp will help to minimize I/O operations. + .EXAMPLE + Disable-LastAccessTimestamp + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build, Filesystem + #> + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable the filesystem last access timestamps')) + { + & fsutil behavior set disablelastaccess 1 | Out-Null + } +} diff --git a/CitrixImagingTools/Public/Disable-OfflineFiles.ps1 b/CitrixImagingTools/Public/Disable-OfflineFiles.ps1 index f49fdc7..440588e 100644 --- a/CitrixImagingTools/Public/Disable-OfflineFiles.ps1 +++ b/CitrixImagingTools/Public/Disable-OfflineFiles.ps1 @@ -16,10 +16,9 @@ .EXAMPLE Disable-OfflineFiles - ToDo: add example output - .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] @@ -33,13 +32,13 @@ Value = 0 } - if ($PSCmdlet.ShouldProcess('Disable offline files on the machine')) + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable offline files on the machine')) { if ($false -eq (Test-Path -Path $Params.Path)) { New-Item -Path $Params.Path -ItemType Directory -Force | Out-Null } - New-ItemProperty @Params -Force + New-ItemProperty @Params -Force | Out-Null } } diff --git a/CitrixImagingTools/Public/Disable-Superfetch.ps1 b/CitrixImagingTools/Public/Disable-Superfetch.ps1 new file mode 100644 index 0000000..c25f891 --- /dev/null +++ b/CitrixImagingTools/Public/Disable-Superfetch.ps1 @@ -0,0 +1,33 @@ +function Disable-Superfetch +{ + <# + .SYNOPSIS + Disables the Superfetch service. + + .DESCRIPTION + Disables Superfetch by turning off its service. + + Superfetch tries to improve system performance over time by "learning" the + typical user activity. This information is stored within the operating system, + which means it is deleted upon each reboot and provides little value in a virtual + desktop environment. + + Windows 8/8.1 should disable the SuperFetch service automatically in pooled virtual + desktops. + + .EXAMPLE + Disable-Superfetch + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable Superfetch')) + { + Stop-Service -Name sysmain -Force -PassThru | Set-Service -StartupType Disabled + } +} diff --git a/CitrixImagingTools/Public/Disable-SystrayIcon.ps1 b/CitrixImagingTools/Public/Disable-SystrayIcon.ps1 index dcdc07f..9c57cb1 100644 --- a/CitrixImagingTools/Public/Disable-SystrayIcon.ps1 +++ b/CitrixImagingTools/Public/Disable-SystrayIcon.ps1 @@ -18,17 +18,24 @@ Function Disable-SystrayIcon - PvsDisk .EXAMPLE - Disable-SystrayIcon + Disable-SystrayIcon -Icon VMwareTools -Verbose - ToDo: add example output + Hides the VMware Tools icon from the systray. + + .EXAMPLE + Disable-SystrayIcon -All -Verbose + + Hides the VMware Tools and PVS vDisk icon from + the systray. .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build, #> - [CmdletBinding(DefaultParameterSetName = 'All', SupportsShouldProcess = $true)] + [CmdletBinding(DefaultParameterSetName = 'CustomSelection', SupportsShouldProcess = $true)] param( - [Parameter(ParameterSetName = 'CustomSelection')] + [Parameter(Mandatory = $true, ParameterSetName = 'CustomSelection')] [ValidateSet('VMwareTools', 'PVSvDisk')] $Icon, @@ -36,9 +43,6 @@ Function Disable-SystrayIcon [switch]$All ) - # Remove duplicates from the icon input - $Icon = $Icon | Select-Object -Unique - if ($All.IsPresent -or 'VMwareTools' -in $Icon) { $VMwareToolsParams = @{ @@ -64,6 +68,7 @@ Function Disable-SystrayIcon if ($PSCmdlet.ShouldProcess('PvsDisk', 'Remove systray icon')) { + # ToDo: Path cannot be found Set-ItemProperty @PVSvDiskParams -Force } } diff --git a/CitrixImagingTools/Public/Disable-TcpTaskOffloading.ps1 b/CitrixImagingTools/Public/Disable-TcpTaskOffloading.ps1 index bce6f2d..76b6f06 100644 --- a/CitrixImagingTools/Public/Disable-TcpTaskOffloading.ps1 +++ b/CitrixImagingTools/Public/Disable-TcpTaskOffloading.ps1 @@ -5,21 +5,23 @@ ToDo: Disables Offline Files which is recommended for always-on systems. .DESCRIPTION - ToDo: The disabling of Offline Files is strongly recommended to prevent Windows from caching - network files on its local disk – a feature with no benefit to a diskless system. + TCP offload engine is a function used in network interface cards (NIC) to offload + processing of the entire TCP/IP stack to the network controller. By moving some or + all of the processing to dedicated hardware, a TCP offload engine frees the system's + main CPU for other tasks. However, TCP offloading has been known to cause some issues, + and disabling it can help avoid these issues. - Offline Files saves a copy of network files on the user's computer for use when the computer - is not connected to the network. - - Note: Changes to this setting do not take effect until the affected computer is restarted. + This function disables all of the task offloads from the TCP/IP stack. .EXAMPLE Disable-TcpTaskOffloading - ToDo: add example output + .LINK + https://docs.microsoft.com/en-us/windows-hardware/drivers/network/using-registry-values-to-enable-and-disable-task-offloading .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: #> [CmdletBinding(SupportsShouldProcess = $true)] @@ -32,8 +34,8 @@ Value = 1 } - if ($PSCmdlet.ShouldProcess('Disable TCP/IP task offload on the machine')) + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Disable TCP/IP task offload on the machine')) { - New-ItemProperty @Params -Force + New-ItemProperty @Params -Force | Out-Null } } diff --git a/CitrixImagingTools/Public/Disable-WindowsUpdate.ps1 b/CitrixImagingTools/Public/Disable-WindowsUpdate.ps1 index 629ace1..19a0e3b 100644 --- a/CitrixImagingTools/Public/Disable-WindowsUpdate.ps1 +++ b/CitrixImagingTools/Public/Disable-WindowsUpdate.ps1 @@ -15,21 +15,25 @@ .EXAMPLE Disable-WindowsUpdate - ToDo: add example output .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Sealing #> [CmdletBinding(SupportsShouldProcess = $true)] param() - $Path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update' + $Params = @{ + Path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update' + PropertyType = 'Dword' + Force = $true + } if ($PSCmdlet.ShouldProcess('Disable automatic update searching & downloading')) { - New-ItemProperty -Force -Path $Path -PropertyType Dword -Name AUOptions -Value 1 - New-ItemProperty -Force -Path $Path -PropertyType Dword -Name ScheduledInstallDay -Value 0 - New-ItemProperty -Force -Path $Path -PropertyType Dword -Name ScheduledInstallTime -Value 3 + New-ItemProperty @Params -Name AUOptions -Value 1 | Out-Null + New-ItemProperty @Params -Name ScheduledInstallDay -Value 0 | Out-Null + New-ItemProperty @Params -Name ScheduledInstallTime -Value 3 | Out-Null } if ($PSCmdlet.ShouldProcess('Stop & disable windows update service')) diff --git a/CitrixImagingTools/Public/Enable-HighPerformancePowerScheme.ps1 b/CitrixImagingTools/Public/Enable-HighPerformancePowerScheme.ps1 new file mode 100644 index 0000000..b9e40ce --- /dev/null +++ b/CitrixImagingTools/Public/Enable-HighPerformancePowerScheme.ps1 @@ -0,0 +1,25 @@ +function Enable-HighPerformancePowerScheme +{ + <# + .SYNOPSIS + Enables the power scheme "High Performance" + + .DESCRIPTION + Enables the power scheme "High Performance". + + .EXAMPLE + Enable-HighPerformancePowerScheme -Verbose + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build, Performance + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Enable High Performance power scheme')) + { + & powercfg.exe -SETACTIVE 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c + } +} diff --git a/CitrixImagingTools/Public/Enable-TargetDeviceGetComputerNameFallback.ps1 b/CitrixImagingTools/Public/Enable-TargetDeviceGetComputerNameFallback.ps1 new file mode 100644 index 0000000..197b00f --- /dev/null +++ b/CitrixImagingTools/Public/Enable-TargetDeviceGetComputerNameFallback.ps1 @@ -0,0 +1,36 @@ +Function Enable-TargetDeviceGetComputerNameFallback +{ + <# + .SYNOPSIS + Configures a fallback to computername instead of mac address if there's a + problem with the bootstrap file. + + .DESCRIPTION + From Citrix Discussions: + What happens is if the name cannot be retrieved from the bootstrap then the + name defaults to the mac address. You can force the target to ask again for + the target's machine name by running this function. + + .EXAMPLE + Enable-TargetDeviceGetComputerNameFallback + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Network, Build + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + $Params = @{ + Path = 'HKLM:\System\CurrentControlSet\services\bnistack\Parameters' + Name = 'EnableGetComputerName' + PropertyType = 'Dword' + Value = 1 + } + + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Enable computer name fallback')) + { + New-ItemProperty @Params -Force | Out-Null + } +} diff --git a/CitrixImagingTools/Public/Get-AutoAdminLogon.ps1 b/CitrixImagingTools/Public/Get-AutoAdminLogon.ps1 index 1c5e4a0..72de910 100644 --- a/CitrixImagingTools/Public/Get-AutoAdminLogon.ps1 +++ b/CitrixImagingTools/Public/Get-AutoAdminLogon.ps1 @@ -16,7 +16,8 @@ Function Get-AutoAdminLogon False .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Credential #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] diff --git a/CitrixImagingTools/Public/Get-DataExecutionPreventionStatus.ps1 b/CitrixImagingTools/Public/Get-DataExecutionPreventionStatus.ps1 new file mode 100644 index 0000000..6dd0c7c --- /dev/null +++ b/CitrixImagingTools/Public/Get-DataExecutionPreventionStatus.ps1 @@ -0,0 +1,89 @@ +function Get-DataExecutionPreventionStatus +{ + <# + .SYNOPSIS + Gets the current DEP status. + + .DESCRIPTION + Gets the current DEP status. + + Data Execution Prevention (DEP) is a set of hardware and software technologies + that perform additional checks on memory to help prevent malicious code from + running on a system. + + The primary benefit of DEP is to help prevent code execution from data pages. + Typically, code is not executed from the default heap and the stack. Hardware-enforced + DEP detects code that is running from these locations and raises an exception when + execution occurs. Software-enforced DEP can help prevent malicious code from taking + advantage of exception-handling mechanisms in Windows. + + .PARAMETER ListAvailable + Lists all available DEP options. + + .EXAMPLE + Get-DataExecutionPreventionStatus | Format-List + + PolicyLevel : OptIn + IsDefault : True + Description : This setting is the default configuration. On systems with processors + that can implement hardware-enforced DEP, DEP is enabled by default for + limited system binaries and programs that "opt-in." With this option, + only Windows system binaries are covered by DEP by default. + + .EXAMPLE + Get-DataExecutionPreventionStatus -ListAvailable | Format-List + + List all available DEP options. + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Runtime, State, Security + + .LINK + https://support.microsoft.com/en-us/help/875352/a-detailed-description-of-the-data-execution-prevention-dep-feature-in + .LINK + https://blogs.technet.microsoft.com/srd/2009/06/12/understanding-dep-as-a-mitigation-technology-part-1/ + #> + [CmdletBinding()] + param( + [switch] $ListAvailable + ) + + $MappingTable = @{ + 0 = [ordered]@{ + PolicyLevel = "AlwaysOff"; + IsDefault = $false; + Description = 'This setting does not provide any DEP coverage for any part of the system, regardless of hardware DEP support.' + } + 1 = [ordered]@{ + PolicyLevel = "AlwaysOn"; + IsDefault = $false; + Description = 'This setting provides full DEP coverage for the whole system. All processes always run with DEP applied. The exceptions list to exempt specific programs from DEP protection is not available. System compatibility fixes for DEP do not take effect. Programs that have been opted-out by using the Application Compatibility Toolkit run with DEP applied.' + } + 2 = [ordered]@{ + PolicyLevel = "OptIn"; + IsDefault = $true; + Description = 'This setting is the default configuration. On systems with processors that can implement hardware-enforced DEP, DEP is enabled by default for limited system binaries and programs that "opt-in." With this option, only Windows system binaries are covered by DEP by default.' + } + 3 = [ordered]@{ + PolicyLevel = "OptOut"; + IsDefault = $false; + Description = 'DEP is enabled by default for all processes. You can manually create a list of specific programs that do not have DEP applied by using the System dialog box in Control Panel. Information technology (IT) professionals can use the Application Compatibility Toolkit to "opt-out" one or more programs from DEP protection. System compatibility fixes, or shims, for DEP do take effect.' + } + + } + + if ($ListAvailable.IsPresent) + { + $MappingTable.GetEnumerator() | ForEach-Object { + [pscustomobject]$_.Value + } + } + else + { + $Result = Get-CimInstance -ClassName win32_operatingsystem -Property DataExecutionPrevention_SupportPolicy + $PolicyID = [int]($Result.DataExecutionPrevention_SupportPolicy) + [pscustomobject]($MappingTable[$PolicyID]) + } + +} diff --git a/CitrixImagingTools/Public/Get-OperatingSystemFamily.ps1 b/CitrixImagingTools/Public/Get-OperatingSystemFamily.ps1 index 0a3b85c..e9590ab 100644 --- a/CitrixImagingTools/Public/Get-OperatingSystemFamily.ps1 +++ b/CitrixImagingTools/Public/Get-OperatingSystemFamily.ps1 @@ -3,7 +3,7 @@ Function Get-OperatingSystemFamily [OutputType([string])] [CmdletBinding(DefaultParameterSetName = 'Query')] Param( - [Parameter(ParameterSetName = 'Resolve')] + [Parameter(Mandatory = $true, ParameterSetName = 'Resolve')] [ValidateNotNullOrEmpty()] $Version, diff --git a/CitrixImagingTools/Public/Get-ProvisioningType.ps1 b/CitrixImagingTools/Public/Get-ProvisioningType.ps1 index 9180c9a..01f0067 100644 --- a/CitrixImagingTools/Public/Get-ProvisioningType.ps1 +++ b/CitrixImagingTools/Public/Get-ProvisioningType.ps1 @@ -18,33 +18,34 @@ function Get-ProvisioningType PVS .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Runtime, State #> [OutputType([string])] [CmdletBinding()] param() - # Check XA/XD agent installation - [bool]$CitrixAgentInstalled = Get-Service -Name "BrokerAgent" -ErrorAction SilentlyContinue - if (-not $CitrixAgentInstalled) - { - throw "No Citrix VDA (MFA) agent found on the system!" - } - try { - if (Select-String -Path 'C:\Personality.ini' -Pattern ([regex]::Escape('$DiskName=')) -ErrorAction Stop) - { - return 'PVS' + $Params = @{ + Namespace = 'root\Citrix\DesktopInformation' + ClassName = 'Citrix_VirtualDesktopInfo' + Property = 'ProvisioningType' } - else + + $Info = Get-CimInstance @Params + + switch ($Info.ProvisioningType) { - return 'MCS' + 'ProvisioningServices' { 'PVS'; break } + 'MachineCreationServices' { 'MCS'; break } + default { 'Manual' } } + } catch { - 'Manual' + throw "No Citrix VDA (MFA) agent found on the system!" } } diff --git a/CitrixImagingTools/Public/Get-PvsRamCache.ps1 b/CitrixImagingTools/Public/Get-PvsRamCache.ps1 index 3ed09db..9b016a8 100644 --- a/CitrixImagingTools/Public/Get-PvsRamCache.ps1 +++ b/CitrixImagingTools/Public/Get-PvsRamCache.ps1 @@ -37,7 +37,6 @@ function Get-PVSRamCache [Parameter(Position = 1, Mandatory = $false)] [Alias("RunAs")] - [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty @@ -50,12 +49,13 @@ function Get-PVSRamCache $HashTable = @{ ComputerName = $Computer Size = 0 - Result = Success + Result = 'Success' } try { - $QueryResult = CimInstance -Query 'Select PoolNonPagedBytes From Win32_PerfFormattedData_PerfOS_Memory' -ComputerName $Computer -Credential $Credential + $CS = New-CimSession -Credential $Credential -ComputerName $Computer + $QueryResult = CimInstance -Query 'Select PoolNonPagedBytes From Win32_PerfFormattedData_PerfOS_Memory' -CimSession $CS $HashTable['Size'] = [math]::truncate(($QueryResult).PoolNonPagedBytes / 1MB) } catch diff --git a/CitrixImagingTools/Public/Get-WindowsEnvironmentVariable.ps1 b/CitrixImagingTools/Public/Get-WindowsEnvironmentVariable.ps1 index 247b479..81b46ad 100644 --- a/CitrixImagingTools/Public/Get-WindowsEnvironmentVariable.ps1 +++ b/CitrixImagingTools/Public/Get-WindowsEnvironmentVariable.ps1 @@ -40,7 +40,8 @@ function Get-WindowsEnvironmentVariable Returns a specific variable from a specific scope. .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Environment, State #> [CmdletBinding()] diff --git a/CitrixImagingTools/Public/Import-IniFile.ps1 b/CitrixImagingTools/Public/Import-IniFile.ps1 index e4c3e09..f1abd3f 100644 --- a/CitrixImagingTools/Public/Import-IniFile.ps1 +++ b/CitrixImagingTools/Public/Import-IniFile.ps1 @@ -34,7 +34,7 @@ Saves the content of the c:\myinifile.ini in a hashtable called $FileContent .Example - $inifilepath | $FileContent = Import-IniFile + $FileContent = $inifilepath | Import-IniFile ----------- Description Gets the content of the ini file passed through the pipe into a hashtable called $FileContent diff --git a/CitrixImagingTools/Public/Invoke-Robocopy.ps1 b/CitrixImagingTools/Public/Invoke-Robocopy.ps1 new file mode 100644 index 0000000..dc813a3 --- /dev/null +++ b/CitrixImagingTools/Public/Invoke-Robocopy.ps1 @@ -0,0 +1,156 @@ +function Invoke-Robocopy +{ + <# + .Synopsis + Wrapper function for robocopy.exe + + .Parameter Path + String. Source path. You can use relative path. + + .Parameter Destination + Array of destination paths. You can use relative paths. + + .Parameter ArgumentList + Array of additional arguments for robocopy.exe + + .Parameter Retry + Integer. Number of retires. Default is 2. + + .Parameter EnableExit + Switch. Exit function if Robocopy throws "terminating" error code. + + .Parameter PassThru + Switch. Returns an object with the following properties: + + StdOut - array of strings captured from StandardOutput + StdErr - array of strings captured from StandardError + ExitCode - Enum with Robocopy exit code in human-readable format + + By default, this function doesn't generate any output. + + .Link + https://technet.microsoft.com/en-us/library/cc733145.aspx + + .Link + http://ss64.com/nt/robocopy.html + + .Link + http://ss64.com/nt/robocopy-exit.html + + .NOTES + Tags: Data + + .Example + 'c:\bravo', 'c:\charlie' | Invoke-Robocopy -Path 'c:\alpha' -ArgumentList @('/xo', '/e' ) + + Copy 'c:\alpha' to 'c:\bravo' and 'c:\charlie'. Copy subdirectories, include empty directories, exclude older files. + #> + + [CmdletBinding()] + Param + ( + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ValidateScript({Test-Path -Path $_})] + [string]$Path, + + [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] + [string[]]$Destination, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [string[]]$ArgumentList, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [int]$Retry = 2, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [switch]$EnableExit, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [switch]$PassThru + ) + + Begin + { + # https://learn-powershell.net/2016/03/07/building-a-enum-that-supports-bit-fields-in-powershell/ + function New-RobocopyHelper + { + $TypeName = 'Robocopy.ExitCode' + + # http://stackoverflow.com/questions/16552801/how-do-i-conditionally-add-a-class-with-add-type-typedefinition-if-it-isnt-add + if (! ([System.Management.Automation.PSTypeName]$TypeName).Type) { + try { + #region Module Builder + $Domain = [System.AppDomain]::CurrentDomain + $DynAssembly = New-Object -TypeName System.Reflection.AssemblyName($TypeName) + $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) # Only run in memory + $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($TypeName, $false) + #endregion Module Builder + + # https://pshirwin.wordpress.com/2016/03/18/robocopy-exitcodes-the-powershell-way/ + #region Enum + $EnumBuilder = $ModuleBuilder.DefineEnum($TypeName, 'Public', [int32]) + [void]$EnumBuilder.DefineLiteral('NoChange', [int32]0x00000000) + [void]$EnumBuilder.DefineLiteral('OKCopy', [int32]0x00000001) + [void]$EnumBuilder.DefineLiteral('ExtraFiles', [int32]0x00000002) + [void]$EnumBuilder.DefineLiteral('MismatchedFilesFolders', [int32]0x00000004) + [void]$EnumBuilder.DefineLiteral('FailedCopyAttempts', [int32]0x00000008) + [void]$EnumBuilder.DefineLiteral('FatalError', [int32]0x000000010) + $EnumBuilder.SetCustomAttribute( + [FlagsAttribute].GetConstructor([Type]::EmptyTypes), + @() + ) + [void]$EnumBuilder.CreateType() + #endregion Enum + } catch { + throw $_ + } + } + } + + New-RobocopyHelper + } + + Process + { + foreach ($item in $Destination) { + # Resolve destination paths, remove trailing backslash, add Retries and combine all arguments into one array + $AllArguments = @( + (Resolve-Path -Path $Path) -replace '\\+$' + ) + ( + $item | ForEach-Object { + $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($_) -replace '\\+$' + } + ) + $ArgumentList + "/R:$Retry" + + # Invoke Robocopy + $Result = Start-ConsoleProcess -FilePath 'robocopy.exe' -ArgumentList $AllArguments + $Result.ExitCode = [Robocopy.ExitCode]$Result.ExitCode + + # Dump Robocopy log to Verbose stream + $Result.StdOut | Write-Verbose + + # Process Robocopy exit code + # http://latkin.org/blog/2012/07/08/using-enums-in-powershell/ + if ($Result.ExitCode -band [Robocopy.ExitCode]'FailedCopyAttempts, FatalError') { + if ($EnableExit) { + $host.SetShouldExit(1) + } else { + $ErrorMessage = @($Result.ExitCode) + ( + # Try to provide additional info about error. + # WARNING: This WILL fail in localized Windows. E.g., "������" in Russian. + $Result.StdOut | Select-String -Pattern '\s*ERROR\s+:\s+(.+)' | ForEach-Object { + $_.Matches.Groups[1].Value + } + ) + + $ErrorMessage -join [System.Environment]::NewLine | Write-Error + } + } else { + # Passthru Robocopy result + if ($PassThru) { + $Result + } + } + } + } +} diff --git a/CitrixImagingTools/Public/Move-EventLog.ps1 b/CitrixImagingTools/Public/Move-EventLog.ps1 index 6e01475..b1ad29d 100644 --- a/CitrixImagingTools/Public/Move-EventLog.ps1 +++ b/CitrixImagingTools/Public/Move-EventLog.ps1 @@ -24,7 +24,8 @@ Sets "%WriteCacheDisk%\EventLogs" as filesystem location. .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Filesystem, Build #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] diff --git a/CitrixImagingTools/Public/Optimize-GlobalAssemblyCache.ps1 b/CitrixImagingTools/Public/Optimize-GlobalAssemblyCache.ps1 new file mode 100644 index 0000000..c08abc2 --- /dev/null +++ b/CitrixImagingTools/Public/Optimize-GlobalAssemblyCache.ps1 @@ -0,0 +1,32 @@ +function Optimize-GlobalAssemblyCache +{ + <# + .SYNOPSIS + Optimizes the global assembly cache by executing queued assembly compilation + jobs. + + .DESCRIPTION + Prevents mscorsvw.exe from needlessly creating high CPU load due to compiling + .NET assemblies in the background during idle time. This command forces all + queued compilation jobs to be executed in order to update the global assembly + cache. + + .EXAMPLE + Optimize-GlobalAssemblyCache -Verbose + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Process, Sealing + #> + + [CmdletBinding()] + param() + + $NgenPath = Get-ChildItem -Path "$env:windir\Microsoft.NET" -Recurse -Filter 'ngen.exe' + + foreach ($ngenExe in $NgenPath.FullName) + { + Write-Verbose -Message ("Precompiling assemblies with [$ngenExe]" | AddPrefix) + Start-Process $ngenExe -ArgumentList 'executeQueuedItems' -Wait + } +} diff --git a/CitrixImagingTools/Public/Optimize-SMBv2.ps1 b/CitrixImagingTools/Public/Optimize-SMBv2.ps1 new file mode 100644 index 0000000..c2c8f09 --- /dev/null +++ b/CitrixImagingTools/Public/Optimize-SMBv2.ps1 @@ -0,0 +1,56 @@ +Function Optimize-SMBv2 +{ + <# + .SYNOPSIS + Optimizes SMBv2 settings. + + .DESCRIPTION + Tweaks the following settinga: + + - By default, the SMB redirector throttles throughput across high-latency network connections + in some cases to avoid network-related timeouts. Setting the DisableBandwidthThrottling + registry value to 1 disables this throttling, enabling higher file transfer throughput over + high-latency network connections. + + - By default, the SMB redirector does not transfer payloads larger than approximately 64 KB per + request. Setting the DisableLargeMtu registry value to 0 enables larger request sizes, which + can improve file transfer speed. + + - By default, Change Notify events are turned on for file and folder changes that occur in + subfolders of a mapped network share. Disable these events causes the server to still send a + Change Notify event when a file or a folder is changed in the root and first folder level of + the mapped network share. However the server does not send a Change Notify event when a change + is made at the level of the second subfolder or deeper in the mapped network share. + + .EXAMPLE + Optimize-SMBv2 + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Network, Build + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param() + + $Params = @{ + PropertyType = 'Dword' + Force = $true + } + + if ($PSCmdlet.ShouldProcess('SMB Redirector', 'Tweak settings')) + { + $Path = 'HKLM:\System\CurrentControlSet\Services\LanmanWorkstation\Parameters' + + New-ItemProperty @Params -Path $Path -Name DisableBandwidthThrottling -Value 1 | Out-Null + New-ItemProperty @Params -Path $Path -Name DisableLargeMtu -Value 0 | Out-Null + } + + + if ($PSCmdlet.ShouldProcess('Change Notify Events', 'Disable')) + { + $Path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer' + + New-ItemProperty @Params -Path $Path -Name NoRemoteRecursiveEvents -Value 1 | Out-Null + } +} diff --git a/CitrixImagingTools/Public/Optimize-WindowsUpdate.ps1 b/CitrixImagingTools/Public/Optimize-WindowsUpdate.ps1 index 1df6f82..8110b62 100644 --- a/CitrixImagingTools/Public/Optimize-WindowsUpdate.ps1 +++ b/CitrixImagingTools/Public/Optimize-WindowsUpdate.ps1 @@ -22,7 +22,8 @@ ToDo: add example output .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build, Cleanup .Link https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/dism-operating-system-package-servicing-command-line-options diff --git a/CitrixImagingTools/Public/Remove-CommonAutostart.ps1 b/CitrixImagingTools/Public/Remove-CommonAutostart.ps1 index 3f13c0a..c4b15bb 100644 --- a/CitrixImagingTools/Public/Remove-CommonAutostart.ps1 +++ b/CitrixImagingTools/Public/Remove-CommonAutostart.ps1 @@ -2,7 +2,7 @@ { <# .SYNOPSIS - Removes common Autostart files + Removes common Autostart files. .DESCRIPTION Deletes files in C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup. @@ -19,7 +19,8 @@ ToDo: add example output .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build, Cleanup #> [CmdletBinding(SupportsShouldProcess = $true)] diff --git a/CitrixImagingTools/Public/Remove-CommonDesktopShortcut.ps1 b/CitrixImagingTools/Public/Remove-CommonDesktopShortcut.ps1 index ce4403c..a9acd94 100644 --- a/CitrixImagingTools/Public/Remove-CommonDesktopShortcut.ps1 +++ b/CitrixImagingTools/Public/Remove-CommonDesktopShortcut.ps1 @@ -13,7 +13,8 @@ function Remove-CommonDesktopShortcut ToDo: add example output .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Filesystem, Cleanup, Build #> [CmdletBinding(SupportsShouldProcess = $true)] diff --git a/CitrixImagingTools/Public/Remove-FloppyCD.ps1 b/CitrixImagingTools/Public/Remove-FloppyCD.ps1 index f2abab5..9998797 100644 --- a/CitrixImagingTools/Public/Remove-FloppyCD.ps1 +++ b/CitrixImagingTools/Public/Remove-FloppyCD.ps1 @@ -15,7 +15,8 @@ Function Remove-FloppyCD ToDo: add example output .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Build #> [CmdletBinding(SupportsShouldProcess = $true)] param() diff --git a/CitrixImagingTools/Public/Set-DiskIOTimeout.ps1 b/CitrixImagingTools/Public/Set-DiskIOTimeout.ps1 new file mode 100644 index 0000000..23b7836 --- /dev/null +++ b/CitrixImagingTools/Public/Set-DiskIOTimeout.ps1 @@ -0,0 +1,44 @@ +function Set-DiskIOTimeout +{ + <# + .SYNOPSIS + Increase/Decrease disk IO Timeout. + + .DESCRIPTION + In peak scenarios the disk may be heavily strained. This setting allows + for a maxmimum timeout of 200 seconds. + + .EXAMPLE + Set-DiskIOTimeout + + Configures the default timeout of 30 seconds + + .EXAMPLE + Set-DiskIOTimeout -Seconds 200 + + Configures a custom timeout of 200 seconds + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Service + #> + + [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')] + param( + [ValidateNotNullOrEmpty()] + [ValidateRange(0,200)] + [int]$Seconds = 30 + ) + + if ($PSCmdlet.ShouldProcess("$Seconds seconds", 'Set disk IO timeout')) + { + $Params = @{ + Path = 'HKLM:\SYSTEM\CurrentControlSet\Services\Disk' + Name = 'TimeOutValue' + Value = $Seconds + PropertyType = 'Dword' + } + + New-ItemProperty @Params -Force | Out-Null + } +} diff --git a/CitrixImagingTools/Public/Set-ServiceStartupTimeout.ps1 b/CitrixImagingTools/Public/Set-ServiceStartupTimeout.ps1 new file mode 100644 index 0000000..4691332 --- /dev/null +++ b/CitrixImagingTools/Public/Set-ServiceStartupTimeout.ps1 @@ -0,0 +1,52 @@ +Function Set-ServiceStartupTimeout +{ + <# + .SYNOPSIS + Increase/Decrease Service Startup Timeout + + .DESCRIPTION + Helps with error 1053: + + --- + The service did not respond in a timely fashion" when attempting to start, stop or pause a service + --- + + When a service starts, the service communicates to the Service Control Manager how long the service + must have to start (the time-out period for the service). If the Service Control Manager does not + receive a "service started" notice from the service within this time-out period, the Service Control + Manager terminates the process that hosts the service. This time-out period is typically less than + 30 seconds. If you do not adjust this time-out period, the Service Control Manager ends the process. + + .EXAMPLE + Set-ServiceStartupTimeout + + Configures the default timeout of 30 seconds + + .EXAMPLE + Set-ServiceStartupTimeout -Seconds 200 + + Configures a custom timeout of 200 seconds + + .NOTES + Original Author: Sebastian Neumann (@megam0rf) + Tags: Service + #> + + [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')] + param( + [ValidateNotNullOrEmpty()] + [ValidateRange(0,999)] + [int]$Seconds = 30 + ) + + if ($PSCmdlet.ShouldProcess("$Seconds seconds", 'Set service timeout')) + { + $Params = @{ + Path = 'HKLM:\SYSTEM\CurrentControlSet\Control' + Name = 'ServicesPipeTimeout' + Value = $Seconds + } + + Set-ItemProperty @Params + } +} diff --git a/CitrixImagingTools/Public/Set-Shortcut.ps1 b/CitrixImagingTools/Public/Set-Shortcut.ps1 index 629f258..8a39735 100644 --- a/CitrixImagingTools/Public/Set-Shortcut.ps1 +++ b/CitrixImagingTools/Public/Set-Shortcut.ps1 @@ -2,25 +2,28 @@ Function Set-Shortcut { <# .SYNOPSIS - Short description + Creates or overwrites file shortcuts (*.lnk). .DESCRIPTION - Long description + Uses a com object to create a file shortcut The link might + additionally specify parameters to be passed to the target + program when it is run. .PARAMETER TargetPath - Parameter description + Specify a path to the target program file/directory. .PARAMETER Arguments - Parameter description + Specify optional arguments for the program under $TargetPath. .PARAMETER DestinationPath - Parameter description + Path where the shortcut is going to be stored. .EXAMPLE ToDo: add examples .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Filesystem #> [CmdletBinding(SupportsShouldProcess = $true)] diff --git a/CitrixImagingTools/Public/Set-SpoolerDirectory.ps1 b/CitrixImagingTools/Public/Set-SpoolerDirectory.ps1 index 4e6340f..016f7b5 100644 --- a/CitrixImagingTools/Public/Set-SpoolerDirectory.ps1 +++ b/CitrixImagingTools/Public/Set-SpoolerDirectory.ps1 @@ -18,14 +18,21 @@ Function Set-SpoolerDirectory .EXAMPLE Set-SpoolerDirectory -Path "$env:WriteCachePath\Spooler" - ToDo: add example output + Changes the printer spooler path to the specified location. + + .EXAMPLE + Set-SpoolerDirectory -RestoreDefaultPath -Verbose + + Restores the printer spooler path to its default location. .NOTES - ToDo: add tags, author info + Original Author: Sebastian Neumann (@megam0rf) + Tags: Filesystem, Build #> + [CmdletBinding(DefaultParameterSetName = 'Default', SupportsShouldProcess = $true)] param( - [Parameter(Mandatory = $true, ParameterSetName = 'Default')] + [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Default')] [ValidateNotNullOrEmpty()] [string] $Path, diff --git a/CitrixImagingTools/Public/Set-TSLogonMode.ps1 b/CitrixImagingTools/Public/Set-TSLogonMode.ps1 index 850f218..ad18c43 100644 --- a/CitrixImagingTools/Public/Set-TSLogonMode.ps1 +++ b/CitrixImagingTools/Public/Set-TSLogonMode.ps1 @@ -37,6 +37,9 @@ .LINK https://github.com/megamorf/CitrixImagingTools/blob/master/CitrixImagingTools/Public/Set-TSLogonMode.ps1 + .LINK + https://github.com/megamorf/CitrixImagingTools/blob/master/CitrixImagingTools/Public/Get-TSLogonMode.ps1 + .EXAMPLE Set-TSLogonMode -Mode ProhibitNewLogonsUntilRestart Drains the RDSH by preventing log on attempts, existing sessions are unaffected. @@ -64,7 +67,7 @@ [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] - $Credential = [System.Management.Automation.PSCredential]::Empty + $Credential ) BEGIN @@ -80,7 +83,8 @@ { foreach ($computer in $Computername) { - $TSSettings = Get-CimInstance @TSSettingsParams -ComputerName $Computer -Credential $Credential + $cs = New-CimSession -ComputerName $computer -Credential $Credential -Verbose:$false + $TSSettings = Get-CimInstance @TSSettingsParams -CimSession $cs switch ($Mode) { @@ -108,10 +112,12 @@ } } - if ($PSCmdlet.ShouldProcess("Set Logon Mode to $Mode", "$computer")) + if ($PSCmdlet.ShouldProcess($Computer, "Set Logon Mode to [$Mode]")) { - $TSSettings | Set-CimInstance -ComputerName $Computer -Credential $Credential + $TSSettings | Set-CimInstance -Verbose:$false } + + Remove-CimSession -CimSession $cs -WhatIf:$false } } } diff --git a/CitrixImagingTools/Public/Set-UniqueDiskID.ps1 b/CitrixImagingTools/Public/Set-UniqueDiskID.ps1 index 03cfb84..a79e8a5 100644 --- a/CitrixImagingTools/Public/Set-UniqueDiskID.ps1 +++ b/CitrixImagingTools/Public/Set-UniqueDiskID.ps1 @@ -38,7 +38,8 @@ function Set-UniqueDiskID Result : Unchanged .NOTES - ToDo: add tags, author info. + Original Author: Sebastian Neumann (@megam0rf) + Tags: Disk, Filesystem, Runtime #> [CmdletBinding(SupportsShouldProcess = $true)] param( diff --git a/CitrixImagingTools/Public/Show-ProgressBar.ps1 b/CitrixImagingTools/Public/Show-ProgressBar.ps1 index 37c57a4..96bafcd 100644 --- a/CitrixImagingTools/Public/Show-ProgressBar.ps1 +++ b/CitrixImagingTools/Public/Show-ProgressBar.ps1 @@ -1,24 +1,30 @@ function Show-ProgressBar { param( - [Parameter(Mandatory = $True)] + [Parameter(Mandatory = $True, ParameterSetName = 'ByProcess')] + [psobject]$Process, + + [Parameter(Mandatory = $True,ParameterSetName = 'ByName')] [string]$ProcessName, [Parameter(Mandatory = $True)] [string]$ActivityText ) - Start-Sleep -Seconds 5 + if($ProcessName) + { + $Process = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue + } for ($i = 0; $i -lt 100; $i++) { if ($i -eq '99') {$i = 0} - $ProcessActive = Get-Process $ProcessName -ErrorAction SilentlyContinue + $ProcessActive = Get-Process -Id $Process.Id -ErrorAction SilentlyContinue if ($null -eq $ProcessActive) { $i = 100 - Write-Progress -Activity 'Finish...wait for next operation in 10 seconds' -PercentComplete $i -Status 'Finish.' + Write-Progress -Activity 'Finished...waiting 10 seconds for next operation' -PercentComplete $i -Status 'Finished.' Start-Sleep -Seconds 10 Write-Progress -Activity 'Done' -Status 'Done' -Completed break diff --git a/CitrixImagingTools/Public/Start-Defragmentation.ps1 b/CitrixImagingTools/Public/Start-Defragmentation.ps1 index e376a97..041feae 100644 --- a/CitrixImagingTools/Public/Start-Defragmentation.ps1 +++ b/CitrixImagingTools/Public/Start-Defragmentation.ps1 @@ -1,6 +1,23 @@ function Start-Defragmentation { - [cmdletbinding(SupportsShouldProcess=$true)] + <# + .SYNOPSIS + Short description + + .DESCRIPTION + Long description + + .PARAMETER DriveLetter + Parameter description + + .EXAMPLE + An example + + .NOTES + General notes + #> + + [cmdletbinding(SupportsShouldProcess = $true)] param( [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] @@ -22,7 +39,7 @@ function Start-Defragmentation Write-Verbose -Message ("Starting defrag" | AddPrefix) - if ($PSCmdlet.ShouldProcess("Defragmenting drive $DriveLetter", "Arguments: $defragargs")) + if ($PSCmdlet.ShouldProcess("Defragment drive $DriveLetter", "Arguments: $defragargs")) { Start-Process defrag.exe -ArgumentList $DriveLetter, $defragargs -Wait } diff --git a/CitrixImagingTools/Public/Start-P2PVS.ps1 b/CitrixImagingTools/Public/Start-P2PVS.ps1 index 5956ddb..5f6235b 100644 --- a/CitrixImagingTools/Public/Start-P2PVS.ps1 +++ b/CitrixImagingTools/Public/Start-P2PVS.ps1 @@ -1,20 +1,26 @@ function Start-P2PVS { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess = $true)] param() # Build Path - $PVSPATH = (Get-PvsPath).FullPath + $PVSPATH = (Get-PvsPath).FullName $TargetOptimizerTool = "$PVSPATH\TargetOSOptimizer.exe" $P2PVSTool = "$PVSPATH\P2PVS.exe" # Optimize image Write-Verbose -Message ("Starting $TargetOptimizerTool in silent mode to optimize master." | AddPrefix) - Start-Process -FilePath $TargetOptimizerTool -ArgumentList '/s' -Wait + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Run target optimizer tool')) + { + Start-Process -FilePath $TargetOptimizerTool -ArgumentList '/s' -Wait + } # Start imaging - Write-Verbose -Message ("Starting P2PVS" | AddPrefix) + Write-Verbose -Message ("Starting P2PVS image capture" | AddPrefix) Write-Verbose -Message ("If you see a Windows pop-up to format the disk, please click Cancel or do nothing" | AddPrefix) - Start-Process -FilePath $P2PVSTool -ArgumentList 'P2PVS C: /AutoFit /L' -Wait -PassThru + if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Start image capture')) + { + Start-Process -FilePath $P2PVSTool -ArgumentList 'P2PVS C: /AutoFit /L' -Wait -PassThru + } } diff --git a/CitrixImagingTools/WIP/Start-SealImage.ps1 b/CitrixImagingTools/Public/Start-SealImage.ps1 similarity index 68% rename from CitrixImagingTools/WIP/Start-SealImage.ps1 rename to CitrixImagingTools/Public/Start-SealImage.ps1 index 44115d8..d0f34b3 100644 --- a/CitrixImagingTools/WIP/Start-SealImage.ps1 +++ b/CitrixImagingTools/Public/Start-SealImage.ps1 @@ -4,22 +4,42 @@ [CmdletBinding(SupportsShouldProcess = $true)] param() + # for readability + $EA = @{ErrorAction = 'SilentlyContinue'} - if ($PSCmdlet.ShouldProcess($env:ComputerName, 'Clear Event Logs')) + Write-Verbose -Message ("Clearing Event Logs" | AddPrefix) + Clear-EventLogFull -Confirm:$false + + if (Get-Service @EA -Name msdtc) { - Get-EventLog -List | ForEach-Object { $_.clear() } - # wevtutil cl system + Write-Verbose -Message ("Resetting Distributed Transaction Coordinator" | AddPrefix) + & msdtc.exe -reset } - # If MS Distributed Transaction Service is installed, run msdtc.exe -reset + if (Get-Service @EA -Name MSMQ) + { + Write-Verbose -Message ("Clearing MS Message Queuing (MSMQ) cache" | AddPrefix) + Get-Service -Name MQAC, MSMQ | Stop-Service -Force + } - # if MS Message Queuing is installed, clear its cache - Get-Service -Name MQAC, MSMQ | Stop-Service + Write-Verbose -Message ("Deleting local profiles that are not required" | AddPrefix) + Remove-UserProfile - # Delete local profiles that are not required + Write-Verbose -Message "Stopping Citrix Profile Manager service" + Stop-Service -Name ctxProfile -Force + + if (Get-Package @EA -Name 'Google Chrome') + { + Write-Verbose -Message ("Removing Google Chrome pecularities" | AddPrefix) + Remove-Item @EA -Force -Path 'HKLM\SOFTWARE\Wow6432Node\Microsoft\Active Setup\Installed Components\{8A69D345-D564-463c-AFF1-A69D9E530F96}' + Remove-Item @EA -Force -Path 'HKLM\SOFTWARE\Wow6432Node\Google\Update\Clients\{8A69D345-D564-463c-AFF1-A69D9E530F96}' + Remove-Item @EA -Force -Path 'HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{8A69D345-D564-463c-AFF1-A69D9E530F96}' - # Stop Citrix Profile Manager service - Stop-Service ctxProfile -Force + Write-Verbose -Message ("Setting Chrome update services to disabled" | AddPrefix) + Stop-Service @EA -Name gupdate, gupdatem -PassThru | Set-Service -StartupType Disabled + } +} +<# # If Citrix Profile Manager is configured via GPO, check that its INI in C:\Program Files\Citrix\User Profile Manager has been renamed Rename-Item "C:\Program Files\Citrix\User Profile Manager\UPMPolicyDefaults_all.ini" UPMPolicyDefaults_all.old -ErrorAction SilentlyContinue @@ -55,7 +75,7 @@ reg delete HKLM\SOFTWARE\Microsoft\SystemCertificates\SMS\Certificates\ /f del /q "C:\Windows\ccm\logs\*.log" #> - <# +<# we clear the key and initiate a successful RDP connection to pull a recent license. reg delete HKLM\Software\Microsoft\MSLicensing\Store\LICENSE000 /f @@ -69,26 +89,15 @@ gci Cert:\LocalMachine\SMS | remove-item write-Output "SMS certificates removed" #> -} +#} <# https://www.citrix.com/blogs/2015/01/19/size-matters-pvs-ram-cache-overflow-sizing/ "Defragment the vDisk before deploying the image and after major changes. Defragmenting the vDisk resulted in write cache savings of up to 30% or more during testing. This will impact any of you who use versioning as defragmenting a versioned vDisk is not recommended. Defragmenting a versioned vDisk will create excessively large versioned disks (.AVHD files). Run defragmentation after merging the vDisk versions.Note: Defragment the vDisk by mounting the .VHD on the PVS server and running a manual defragmentation on it. This allows for a more robust defragmentation as the OS is not loaded. An additional 15% reduction in the write cache size was seen with this approach over standard defragmentation." #> - -<# -Write-warning "Removing Google Chrome pecularities" -reg delete 'HKLM\SOFTWARE\Wow6432Node\Microsoft\Active Setup\Installed Components\{8A69D345-D564-463c-AFF1-A69D9E530F96}' /f -reg delete 'HKLM\SOFTWARE\Wow6432Node\Google\Update\Clients\{8A69D345-D564-463c-AFF1-A69D9E530F96}' /f -reg delete 'HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{8A69D345-D564-463c-AFF1-A69D9E530F96}' /f -Write-Warning "Setting Chrome update services to disabled" -c:\windows\system32\sc config gupdatem start= disabled -c:\windows\system32\sc config gupdate start= disabled -#> - <# -# Clear cached DHCP settings to prevent BSOD +Write-Verbose Clear cached DHCP settings to prevent BSOD stop-service dhcp Windows Registry Editor Version 5.00 @@ -107,3 +116,10 @@ Windows Registry Editor Version 5.00 “DhcpNameServer”=”” “DhcpDefaultGateway”=”” #> + + $OS = Get-OperatingSystemFamily + + if($OS -eq "Windows 10") + { + Get-AppxPackage -AllUsers | Remove-AppxPackage + } diff --git a/CitrixImagingTools/WIP/OptimizationSteps.ps1 b/CitrixImagingTools/WIP/OptimizationSteps.ps1 index 3748763..fcc7f61 100644 --- a/CitrixImagingTools/WIP/OptimizationSteps.ps1 +++ b/CitrixImagingTools/WIP/OptimizationSteps.ps1 @@ -22,8 +22,29 @@ at HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Network #endregion +#region disable memory dump creation +#[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl] +“CrashDumpEnabled”=dword:00000000 +“LogEvent”=dword:00000000 +“SendAlert”=dword:00000000 +#endregion + #region Increase Service Startup Timeout Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control' -Name ServicesPipeTimeout -Value #dword:0002bf20 #endregion + + +# services server 2016 +# https://blogs.technet.microsoft.com/secguide/2017/05/29/guidance-on-disabling-system-services-on-windows-server-2016-with-desktop-experience/ + +# disable indexing service +# Before switching vDisk to Standard Image mode: “ipconfig/release” (release DHCP address). + +<# +Alignment issues +Constructed with extra byte at end of file +Dynamic VHD always misaligns disk with storage +Use only fixed-size VHDs for write-cache drives and Provisioning services vDisks. +#>