01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # This function checks on whether a particular app has a corresponding PowerShell wrapper. If it does, then the program will attempt to match the installed version of such app with that which is currently available with PowerShell's module. $appName ='batman ' function includePowerShellWrapper($appName){ # Ensure that PowerShell is using TLS 1.2 in this session [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Uncomment these lines to make TLS1.2 defaults on next reboot #Set-ItemProperty -Path ' HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319 ' -Name ' SchUseStrongCrypto ' -Value ' 1 ' -Type DWord #Set-ItemProperty -Path ' HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319 ' -Name ' SchUseStrongCrypto ' -Value ' 1 ' -Type DWord # Deterministic verification on whether module commands are able to load Import-Module $appName -ea SilentlyContinue $moduleIsLoaded=Get-Command -Module $appName -ea SilentlyContinue # Sanity check: validate module name before proceeding $moduleVersion=.{$y=find-module $appName -ea SilentlyContinue;if($y){return $y.Version.ToString()}} if(!$moduleVersion){write-warning "' $( $appName .ToUpper()) ' doesn' t match PowerShell module"; return $false } elseif (! $moduleIsLoaded ){ # Part A) Compare the installed module with its online counter-part; install if necessary # Select Major, Minor, and Build - omitting Revision. # This is because PowerShell wrapper will deem an installed binary as compatible as long as those values match $installedVersion =.{ $x = Get-Module $appName -ea SilentlyContinue; if ( $x ){ return $x .Version.ToString()}} $targetVersion =.{try{ [void] ( $moduleVersion -match '^(\d+\.\d+\.{0,1}\d+)' ); $matches [1]}catch{}} if ( $matches ){ Clear-Variable -name matches} write-host "$($appName.ToUpper()) PowerShell wrapper`: Installed $installedVersion v.s Updated version $moduleVersion" if ( $installedVersion -ne $moduleVersion ){ write-host "Attempting to install the module $appName $moduleVersion" Remove-Module $appName -ea SilentlyContinue try{ Install-Module -Name $appName -Force -Confirm : $false ; Import-Module $appName ; write-host "$appName PowerShell wrapper module has been installed." return $true } catch{ if (!( 'NuGet' -in ( get-packageprovider ).Name)){ try{ Install-PackageProvider -Name NuGet -MinimumVersion '2.8.5.201' -Force -Confirm : $false -ErrorAction Stop; Install-Module -Name $appName -Force -Confirm : $false ; Import-Module $appName ; write-host "$appName PowerShell wrapper module has been installed." } catch{ write-host "$error" write-warning "Unable to install $appName module" return $false } } } } # Part B) Check Installed applications and upgrade/downgrade as necessary $installedApps = Get-CimInstance -ClassName win32_InstalledWin32Program -ErrorAction SilentlyContinue |select Name,Version $appwizAppExists =.{try{ $matchApp = $installedApps |?{ $_ .Name -like "*$appName*" |select -First 1 } if ( $matchApp ){ $matchApp } else { $false }}catch{}} $appwizVersion =.{try{ [void] ($( if ( $appwizAppExists ){ $appwizAppExists .Version} else { $false }) -match '^(\d+\.\d+\.{0,1}\d+)' ); $matches [1]}catch{}} if ( $matches ){ Clear-Variable -name matches} write-host "Application Wizard version being detected: $appwizAppExists" $isAppwizSameVersion = $targetVersion -eq $appwizVersion $chocoInstalledApps =choco list -l $chocoAppExists = $chocoInstalledApps |?{ $_ -like "*$appName*" } |select -First 1 $chocoVersion =.{try{ [void] ($(.{ [void] ( $chocoAppExists -match ' ([\d+\.]+)' ); return $matches [1]}) -match '^(\d+\.\d+\.{0,1}\d+)' ); $matches [1]}catch{}} if ( $matches ){ Clear-Variable -name matches} write-host "Choco version being detected: $chocoAppExists" $isChocoSameVersion = $targetVersion -eq $chocoVersion write-host "Target version: $targetVersion, Appwiz version: $appwizVersion, Choco version: $chocoVersion" if (!( $isAppwizSameVersion -or $isChocoSameVersion )){ write-host "Now trying to install $appname..." if (!( Get-Command choco.exe -ErrorAction SilentlyContinue)) { Set-ExecutionPolicy Bypass -Scope Process -Force ; iex (( New-Object System.Net.WebClient).DownloadString( 'https://chocolatey.org/install.ps1' ))} try{ if (! $chocoAppExists -and ! $appwizAppExists ){choco install $appName --version= $targetVersion -y } elseif (! $isChocoSameVersion -and ! $isAppwizSameVersion ){choco install $appName --version= $targetVersion --force -y } write-host "Application $appName $targetVersion is now installed" if ( $matches ){ Clear-Variable -name matches} return $true } catch{ write-warning "Unable to install the app name $appName $targetVersion using Chocolatey." if ( $matches ){ Clear-Variable -name matches} return $false } } else { write-host "$appName is already installed." ; if ( $matches ){ Clear-Variable -name matches} return $true } } else { write-host "$($appName.ToUpper()) module has loaded successfully." ; return $true } } includePowerShellWrapper $appName |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # This function doesn't work. I'll leave it here for documentation purposes $appName = 'uga-uga' # Import module winSCP as it does not support module autoloading function includeAppWithPowerShellWrapper( $appName ){ $ErrorActionPreference = "Stop" # Install Chocolatey if (!( Get-Command choco.exe -ErrorAction SilentlyContinue)) { Set-ExecutionPolicy Bypass -Scope Process -Force ; iex (( New-Object System.Net.WebClient).DownloadString( 'https://chocolatey.org/install.ps1' ))} try{ $appExists =choco list -l |?{ $_ -like "*$appName*" } if (! $appExists ){choco install $appName -y } $chocoList =choco list -l $appVersion =.{ $match = $chocoList |?{ $_ -like "$appName*" } |select -first 1 if ( $match ){ [void] ( $match -match "([\.\d]+)" ); return $matches [1]} else { return $null }} } catch{ write-warning "$Error" break ; } # Install module if it's not already available if (!( Get-Module -ListAvailable -Name $appName -ea SilentlyContinue)){ if (!('MyNuGet ' -in (get-packagesource).Name)){ try{ Register-PackageSource -Name MyNuGet -Location https://www.nuget.org/api/v2 -ProviderName NuGet -Force } catch{ Set-ItemProperty -Path ' HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319 ' -Name ' SchUseStrongCrypto ' -Value ' 1 ' -Type DWord Set-ItemProperty -Path ' HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319 ' -Name ' SchUseStrongCrypto ' -Value ' 1' -Type DWord [Net.ServicePointManager] ::SecurityProtocol = [Net.SecurityProtocolType] ::Tls12 Register-PackageSource -Name MyNuGet -Location https://www.nuget.org/api/v2 -ProviderName NuGet -Force } } Install-Package $appName -RequiredVersion $appVersion -Force -Confirm : $false } # Wrapper installed without the WinSCP software binaries #Exception calling "Open" with "1" argument(s): "The winscp.exe executable was not found at location of the assembly #WinSCPnet (C:\Program Files\WindowsPowerShell\Modules\winscp\5.17.5.3\lib), nor in an installation path. You may use #Session.ExecutablePath property to explicitly set path to winscp.exe." #At line:1 char:1 #+ $session = (New-Object WinSCP.Session).Open($sessionOptions) #+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # + CategoryInfo : NotSpecified: (:) [], MethodInvocationException # + FullyQualifiedErrorId : SessionLocalException # Mismatch versions between PowerShell wrapper and Choco installed version #Exception calling "Open" with "1" argument(s): "The version of C:\Program Files (x86)\WinSCP\winscp.exe (5.17.6.0) #does not match version of this assembly C:\Program Files\WindowsPowerShell\Modules\winscp\5.17.5.3\lib\WinSCPNet.dll #(5.17.5.0)." #At line:1 char:1 #+ $session = (New-Object WinSCP.Session).Open($sessionOptions) #+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # + CategoryInfo : NotSpecified: (:) [], MethodInvocationException # + FullyQualifiedErrorId : SessionLocalException } includeAppWithPowerShellWrapper $appName |
Categories: