From d629cb238e418e015af5bca10d74f07b5dd08e3c Mon Sep 17 00:00:00 2001 From: FlorianSf Date: Tue, 16 Jul 2024 10:42:45 +0200 Subject: [PATCH] Updating boilerplate for job management in #13 --- AptecoPSFramework/boilerplate/broadcast.ps1 | 320 +++++++++++------- .../boilerplate/getmessagelists.ps1 | 284 ++++++++++++---- AptecoPSFramework/boilerplate/getmessages.ps1 | 85 ++--- .../boilerplate/getresponses.ps1 | 64 +--- AptecoPSFramework/boilerplate/preview.ps1 | 311 +++++++++++------ AptecoPSFramework/boilerplate/test.ps1 | 310 +++++++++++------ AptecoPSFramework/boilerplate/testsend.ps1 | 311 +++++++++++------ AptecoPSFramework/boilerplate/upload.ps1 | 73 ++-- 8 files changed, 1080 insertions(+), 678 deletions(-) diff --git a/AptecoPSFramework/boilerplate/broadcast.ps1 b/AptecoPSFramework/boilerplate/broadcast.ps1 index 1c4e828..9bf2464 100644 --- a/AptecoPSFramework/boilerplate/broadcast.ps1 +++ b/AptecoPSFramework/boilerplate/broadcast.ps1 @@ -9,21 +9,26 @@ Param( [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] - [hashtable]$params = [Hashtable]@{}, + [hashtable]$params = [Hashtable]@{} - [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] - [String]$jsonParams = "" + #,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] + #[String]$JsonParams = "" + + ,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$JobId = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$SettingsFile = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$ProcessId = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] + [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$DebugMode = "false" # This is a string, because when sent trough multiple processes, only text can be transferred instead of native objects ) -# If this script is called by itself, re-transform the escaped json string input back into a hashtable -If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params = [Hashtable]@{} - ( $jsonParams.replace("'",'"') | convertfrom-json ).psobject.properties | ForEach-Object { - Write-verbose "$( $_.Name ) - $( $_.Value )" - $params[$_.Name] = $_.Value - } -} #----------------------------------------------- # DEBUG SWITCH @@ -31,6 +36,12 @@ If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { $debug = $false +If ( $DebugMode -eq "true" ) { + $debug = $true +} +# TODO make an example lie +# . ./upload.ps -JobId 123 -DebugMode + #----------------------------------------------- # ADD MODULE PATH, IF NOT PRESENT @@ -66,7 +77,7 @@ $Env:Path = ( $scriptPath | Sort-Object -unique ) -join ";" # INPUT PARAMETERS, IF DEBUG IS TRUE #----------------------------------------------- -if ( $debug -eq $true -and $jsonParams -eq "" ) { +if ( $debug -eq $true ) { $params = [hashtable]@{ # Automatic parameters @@ -86,196 +97,267 @@ if ( $debug -eq $true -and $jsonParams -eq "" ) { # Integration parameters #Force64bit = "true" - settingsFile = '.\settings.json' + #ForceCore = "true" + #ForcePython = "true" + settingsFile = '.\inx.yaml' } } -#Write-Log -message "Got a file with these arguments: $( [Environment]::GetCommandLineArgs() )" -writeToHostToo $false - - ################################################ # -# NOTES +# CHECKS # ################################################ -<# - -bla bla - -# TODO [x] encrypt the global db parameter -# TODO [ ] activate the clear log functionality +#----------------------------------------------- +# DEFAULT VALUES +#----------------------------------------------- -#> +$useJob = $false +$enforce64Bit = $false +$enforceCore = $false +$enforcePython = $false +$isPsCoreInstalled = $false -################################################ -# -# SCRIPT ROOT -# -################################################ -<# -if ( $debug -eq $true ) { +#----------------------------------------------- +# CHECK INPUT +#----------------------------------------------- - if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") { - $scriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition +If ( $PsCmdlet.ParameterSetName -eq "JobIdInput" ) { + If ( $SettingsFile -eq "" ) { + throw "Please define a settings file" } else { - $scriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) + $settingsfileLocation = $SettingsFile + $useJob = $true } +} else { + $settingsfileLocation = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($params.settingsFile) +} - $params.scriptPath = $scriptPath +#----------------------------------------------- +# CHECK THE MODE THAT SHOULD BE USED +#----------------------------------------------- + +# Start this if 64 is needed to enforce when this process is 32 bit and system is able to handle it +If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq $false -and [System.Environment]::Is64BitOperatingSystem -eq $true ) { + $enforce64Bit = $true + $useJob = $true } -# Some local settings -$dir = $params.scriptPath -Set-Location $dir -#> +# When you want to use PSCore with 32bit, please change that path in the settings file +If ( $params.ForceCore -eq "true" ) { + $enforceCore = $true + $useJob = $true +} -# Set current location to the settings files directory -$settingsFile = Get-Item $params.settingsFile -Set-Location $settingsFile.DirectoryName +If ( $params.ForcePython -eq "true" ) { + $enforcePython = $true + $useJob = $true +} ################################################ # -# 64 BIT CHECK +# SETTINGS # ################################################ -$thisScript = ".\broadcast.ps1" +#----------------------------------------------- +# CHANGE PATH +#----------------------------------------------- + +# Set current location to the settings files directory +$settingsFileItem = Get-Item $settingsfileLocation +Set-Location $settingsFileItem.DirectoryName #----------------------------------------------- -# CHECK IF 64 BIT SHOULD BE ENFORCED +# IMPORT MODULE #----------------------------------------------- -# Start this if 64 is needed to enforce when this process is 32 bit and system is able to handle it -If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq $false -and [System.Environment]::Is64BitOperatingSystem -eq $true ) { +If ($debug -eq $true) { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" -Verbose +} else { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" +} - $markerGuid = [guid]::NewGuid().toString() - try { +#----------------------------------------------- +# SET DEBUG MODE +#----------------------------------------------- - # Input parameter must be a string and for json the double quotes need to be escaped - $params.Add("markerGuid", $markerGuid) - $paramInput = ( ConvertTo-Json $params -Compress -Depth 99 ).replace('"',"'") +Set-DebugMode -DebugMode $debug - # This inputs a string into powershell exe at a virtual place "sysnative" - # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json - $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JsonParams $paramInput -InformationAction "Continue" - } catch { - Exit 1 - } +#----------------------------------------------- +# SET SETTINGS +#----------------------------------------------- - # Check for warnings and errors - $j | ForEach-Object { - $jrow = $_ - Switch -Wildcard ( $jrow ) { +# Set the settings +If ( $useJob -eq $true -and $ProcessId -ne "") { + Import-Settings -Path $settingsfileLocation -ProcessId $ProcessId +} else { + Import-Settings -Path $settingsfileLocation +} - "INFO*" { - Write-Information -MessageData $jrow -Tags @("Info") -InformationAction Continue - } +# Get all settings +$s = Get-Settings - "WARNING*" { - Write-Warning -Message $jrow - } - "WARNUNG*" { - Write-Warning -Message $jrow - } +#----------------------------------------------- +# ADD JOB +#----------------------------------------------- - } +If ( $params.UseJob -eq "true" -or $useJob -eq $true -and $PsCmdlet.ParameterSetName -eq "HashtableInput") { + + # Create a new job + $jobId = Add-JobLog + $jobParams = [Hashtable]@{ + "JobId" = $JobId + #"Plugin" = $script:settings.plugin.guid + "InputParam" = $params + #"Status" = "Starting" + "DebugMode" = $debug } + Update-JobLog @jobParams - # Convert the PSCustomObject back to a hashtable - $markerRow = $j.IndexOf($markerGuid) - ( convertfrom-json $j[$markerRow+1].replace("'",'"') ) #.trim() +} + + +#----------------------------------------------- +# FIND OUT ABOUT PS CORE +#----------------------------------------------- + +$calc = . $s.psCoreExePath { 1+1 } +if ( $calc -eq 2 ) { + $isPsCoreInstalled = $true +} - Exit 0 +#----------------------------------------------- +# FIND OUT THE MODE +#----------------------------------------------- +$mode = "function" +If ( $enforce64Bit -eq $true ) { + $mode = "PSWin64" +} elseif ( $enforceCore -eq $true ) { + $mode = "PSCore" +} elseif ( $enforcePython -eq $true ) { + $mode = "Python" } ################################################ # -# SETTINGS +# PROGRAM # ################################################ - #----------------------------------------------- -# IMPORT MODULE +# CALL UPLOAD #----------------------------------------------- -If ($debug -eq $true) { - Import-Module "AptecoPSFramework" -Verbose -} else { - Import-Module "AptecoPSFramework" -} +$thisScript = ".\broadcast.ps1" -#----------------------------------------------- -# SET DEBUG MODE -#----------------------------------------------- +# Added try/catch again because of extras.xml wrapper +try { -Set-DebugMode -DebugMode $debug + # Do the upload + Switch ( $mode ) { + "function" { -#----------------------------------------------- -# SET SETTINGS -#----------------------------------------------- + If ( $useJob -eq $true ) { + Invoke-Broadcast -JobId $jobId + } else { + $return = Invoke-Broadcast -InputHashtable $params + } -# Set the settings -Import-Settings -Path $params.settingsFile + break + } -################################################ -# -# PROGRAM -# -################################################ + "PSWin64" { + # This inputs a string into powershell exe at a virtual place "sysnative" + $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" -# TODO [x] check if we need to make a try catch here -> not needed, if we use a combination like + break -<# - $msg = "Temporary count of $( $mssqlResult ) is less than $( $rowsCount ) in the original export. Please check!" - Write-Log -Message $msg -Severity ERROR - throw [System.IO.InvalidDataException] $msg + } -or - Write-Log -Message "Failed to connect to SQLServer database" -Severity ERROR - Write-Log -Message $_.Exception -Severity ERROR - throw $_ + "PSCore" { -#> + # Check if ps core is installed + If ( $isPsCoreInstalled -eq $false ) { + throw "PowerShell Core does not seem to be installed or found" + } + + # This inputs a string into powershell exe at a virtual place "sysnative" + # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json + $j = . $s.psCoreExePath -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + break + } -#----------------------------------------------- -# CALL UPLOAD -#----------------------------------------------- -# Added try/catch again because of extras.xml wrapper -try { + "Python" { - # Do the upload - $return = Invoke-Broadcast $params + <# + + assuming you have a python file like add.py and this content - # Return the values, if succeeded - If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params.markerGuid # Output a guid to find out the separator - ( ConvertTo-Json $return -Depth 99 -Compress ).replace('"',"'") # output the result as json + ```Python + import sys + + # This program adds two numbers + num1 = float(sys.argv[1]) + num2 = 6.3 + + # Add two numbers + sum = num1 + num2 + + # Display the sum + print('The sum of {0} and {1} is {2}'.format(num1, num2, sum)) + ``` + + #> + + # Then it can be called like this + . $s.pythonPath add.py "5.5" + + break + } + + } + + # return + If ( $LASTEXITCODE -ne 0 ) { + $j } else { + If ( $useJob -eq $true ) { + $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput + $return = $jobReturn.output + } $return } + } catch { throw $_ Exit 1 +} finally { + + # Close the connection to joblog + If ( $useJob -eq $true ) { + Close-JobLogDatabase + } + } diff --git a/AptecoPSFramework/boilerplate/getmessagelists.ps1 b/AptecoPSFramework/boilerplate/getmessagelists.ps1 index d8b4db3..5c31b82 100644 --- a/AptecoPSFramework/boilerplate/getmessagelists.ps1 +++ b/AptecoPSFramework/boilerplate/getmessagelists.ps1 @@ -9,21 +9,26 @@ Param( [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] - [hashtable]$params = [Hashtable]@{}, + [hashtable]$params = [Hashtable]@{} - [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] - [String]$jsonParams = "" + #,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] + #[String]$JsonParams = "" + + ,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$JobId = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$SettingsFile = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$ProcessId = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] + [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$DebugMode = "false" # This is a string, because when sent trough multiple processes, only text can be transferred instead of native objects ) -# If this script is called by itself, re-transform the escaped json string input back into a hashtable -If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params = [Hashtable]@{} - ( $jsonParams.replace("'",'"') | convertfrom-json ).psobject.properties | ForEach-Object { - Write-verbose "$( $_.Name ) - $( $_.Value )" - $params[$_.Name] = $_.Value - } -} #----------------------------------------------- # DEBUG SWITCH @@ -31,6 +36,12 @@ If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { $debug = $false +If ( $DebugMode -eq "true" ) { + $debug = $true +} +# TODO make an example lie +# . ./upload.ps -JobId 123 -DebugMode + #----------------------------------------------- # ADD MODULE PATH, IF NOT PRESENT @@ -71,9 +82,13 @@ if ( $debug -eq $true -and $jsonParams -eq "" ) { $params = [hashtable]@{ Password = 'ko' Username = 'ko' - #scriptPath = 'C:\faststats\Scripts\cleverreach' - settingsFile = '.\settings.json' + + # Integration parameters #Force64bit = "true" + #ForceCore = "true" + #ForcePython = "true" + #UseJob = "true" + settingsFile = '.\inx.yaml' } } @@ -81,66 +96,56 @@ if ( $debug -eq $true -and $jsonParams -eq "" ) { ################################################ # -# NOTES +# CHECKS # ################################################ -<# - -bla bla - -#> - - -################################################ -# -# SCRIPT ROOT -# -################################################ +#----------------------------------------------- +# DEFAULT VALUES +#----------------------------------------------- -# Set current location to the settings files directory -$settingsFile = Get-Item $params.settingsFile -Set-Location $settingsFile.DirectoryName +$useJob = $false +$enforce64Bit = $false +$enforceCore = $false +$enforcePython = $false +$isPsCoreInstalled = $false -################################################ -# -# 64 BIT CHECK -# -################################################ +#----------------------------------------------- +# CHECK INPUT +#----------------------------------------------- -$thisScript = ".\getmessagelists.ps1" +If ( $PsCmdlet.ParameterSetName -eq "JobIdInput" ) { + If ( $SettingsFile -eq "" ) { + throw "Please define a settings file" + } else { + $settingsfileLocation = $SettingsFile + $useJob = $true + } +} else { + $settingsfileLocation = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($params.settingsFile) +} #----------------------------------------------- -# CHECK IF 64 BIT SHOULD BE ENFORCED +# CHECK THE MODE THAT SHOULD BE USED #----------------------------------------------- # Start this if 64 is needed to enforce when this process is 32 bit and system is able to handle it If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq $false -and [System.Environment]::Is64BitOperatingSystem -eq $true ) { + $enforce64Bit = $true + $useJob = $true +} - $markerGuid = [guid]::NewGuid().toString() - - try { - - # Input parameter must be a string and for json the double quotes need to be escaped - $params.Add("markerGuid", $markerGuid) - $paramInput = ( ConvertTo-Json $params -Compress -Depth 99 ).replace('"',"'") - - # This inputs a string into powershell exe at a virtual place "sysnative" - # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json - $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JsonParams $paramInput -InformationAction "Continue" - - } catch { - Exit 1 - } - - # Convert the PSCustomObject back to a hashtable - $markerRow = $j.IndexOf($markerGuid) - ( convertfrom-json $j[$markerRow+1].replace("'",'"') ) #.trim() - - Exit 0 +# When you want to use PSCore with 32bit, please change that path in the settings file +If ( $params.ForceCore -eq "true" ) { + $enforceCore = $true + $useJob = $true +} +If ( $params.ForcePython -eq "true" ) { + $enforcePython = $true + $useJob = $true } @@ -150,14 +155,23 @@ If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq # ################################################ +#----------------------------------------------- +# CHANGE PATH +#----------------------------------------------- + +# Set current location to the settings files directory +$settingsFileItem = Get-Item $settingsfileLocation +Set-Location $settingsFileItem.DirectoryName + + #----------------------------------------------- # IMPORT MODULE #----------------------------------------------- If ($debug -eq $true) { - Import-Module "AptecoPSFramework" -Verbose + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" -Verbose } else { - Import-Module "AptecoPSFramework" + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" } @@ -169,16 +183,61 @@ Set-DebugMode -DebugMode $debug #----------------------------------------------- -# SETTINGS +# SET SETTINGS #----------------------------------------------- # Set the settings -<# -$settings = Get-settings -$settings.logfile = ".\file.log" -Set-Settings -PSCustom $settings -#> -Import-Settings -Path $params.settingsFile +If ( $useJob -eq $true -and $ProcessId -ne "") { + Import-Settings -Path $settingsfileLocation -ProcessId $ProcessId +} else { + Import-Settings -Path $settingsfileLocation +} + +# Get all settings +$s = Get-Settings + + +#----------------------------------------------- +# ADD JOB +#----------------------------------------------- + +If ( $params.UseJob -eq "true" -or $useJob -eq $true -and $PsCmdlet.ParameterSetName -eq "HashtableInput") { + + # Create a new job + $jobId = Add-JobLog + $jobParams = [Hashtable]@{ + "JobId" = $JobId + #"Plugin" = $script:settings.plugin.guid + "InputParam" = $params + #"Status" = "Starting" + "DebugMode" = $debug + } + Update-JobLog @jobParams + +} + + +#----------------------------------------------- +# FIND OUT ABOUT PS CORE +#----------------------------------------------- + +$calc = . $s.psCoreExePath { 1+1 } +if ( $calc -eq 2 ) { + $isPsCoreInstalled = $true +} + +#----------------------------------------------- +# FIND OUT THE MODE +#----------------------------------------------- + +$mode = "function" +If ( $enforce64Bit -eq $true ) { + $mode = "PSWin64" +} elseif ( $enforceCore -eq $true ) { + $mode = "PSCore" +} elseif ( $enforcePython -eq $true ) { + $mode = "Python" +} ################################################ @@ -188,26 +247,107 @@ Import-Settings -Path $params.settingsFile ################################################ #----------------------------------------------- -# GET MESSAGELISTS +# CALL MESSAGELISTS #----------------------------------------------- +$thisScript = ".\getmessagelists.ps1" + + # Added try/catch again because of extras.xml wrapper try { # Do the upload - $return = Get-Groups -InputHashtable $params + Switch ( $mode ) { + + "function" { + + If ( $useJob -eq $true ) { + Get-Groups -JobId $jobId + } else { + $return = Get-Groups -InputHashtable $params + } + + break + } + - # Return the values, if succeeded - If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params.markerGuid # Output a guid to find out the separator - ( ConvertTo-Json $return -Depth 99 -Compress ).replace('"',"'") # output the result as json + "PSWin64" { + + # This inputs a string into powershell exe at a virtual place "sysnative" + $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + + } + + + "PSCore" { + + # Check if ps core is installed + If ( $isPsCoreInstalled -eq $false ) { + throw "PowerShell Core does not seem to be installed or found" + } + + # This inputs a string into powershell exe at a virtual place "sysnative" + # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json + $j = . $s.psCoreExePath -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + } + + + "Python" { + + <# + + assuming you have a python file like add.py and this content + + ```Python + import sys + + # This program adds two numbers + num1 = float(sys.argv[1]) + num2 = 6.3 + + # Add two numbers + sum = num1 + num2 + + # Display the sum + print('The sum of {0} and {1} is {2}'.format(num1, num2, sum)) + ``` + + #> + + # Then it can be called like this + . $s.pythonPath add.py "5.5" + + break + } + + } + + # return + If ( $LASTEXITCODE -ne 0 ) { + $j } else { + If ( $useJob -eq $true ) { + $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput + $return = $jobReturn.output + } $return } + } catch { throw $_ Exit 1 +} finally { + + # Close the connection to joblog + If ( $useJob -eq $true ) { + Close-JobLogDatabase + } + } diff --git a/AptecoPSFramework/boilerplate/getmessages.ps1 b/AptecoPSFramework/boilerplate/getmessages.ps1 index 14d05ce..f5c573a 100644 --- a/AptecoPSFramework/boilerplate/getmessages.ps1 +++ b/AptecoPSFramework/boilerplate/getmessages.ps1 @@ -1,5 +1,4 @@  - ################################################ # # INPUT @@ -81,14 +80,19 @@ $Env:Path = ( $scriptPath | Sort-Object -unique ) -join ";" if ( $debug -eq $true ) { $params = [hashtable]@{ + + # Automatic parameters Password = 'ko' Username = 'ko' - #scriptPath = 'C:\faststats\Scripts\cleverreach' - settingsFile = '.\inx.yaml' #mode='taggingOnly' - Force64bit = "true" + + # Integration parameters + #Force64bit = "true" #ForceCore = "true" #ForcePython = "true" + #UseJob = "true" + settingsFile = '.\inx.yaml' + } } @@ -108,6 +112,7 @@ $useJob = $false $enforce64Bit = $false $enforceCore = $false $enforcePython = $false +$isPsCoreInstalled = $false #----------------------------------------------- @@ -215,6 +220,16 @@ If ( $params.UseJob -eq "true" -or $useJob -eq $true -and $PsCmdlet.ParameterSet } + +#----------------------------------------------- +# FIND OUT ABOUT PS CORE +#----------------------------------------------- + +$calc = . $s.psCoreExePath { 1+1 } +if ( $calc -eq 2 ) { + $isPsCoreInstalled = $true +} + #----------------------------------------------- # FIND OUT THE MODE #----------------------------------------------- @@ -265,26 +280,6 @@ try { # This inputs a string into powershell exe at a virtual place "sysnative" $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" - # Check for warnings and errors - $j | ForEach-Object { - $jrow = $_ - Switch -Wildcard ( $jrow ) { - - "INFO*" { - Write-Information -MessageData $jrow -Tags @("Info") -InformationAction Continue - } - - "WARNING*" { - Write-Warning -Message $jrow - } - - "WARNUNG*" { - Write-Warning -Message $jrow - } - - } - } - break } @@ -293,14 +288,7 @@ try { "PSCore" { # Check if ps core is installed - try { - $calc = . $s.psCoreExePath { 1+1 } - if ( $calc -eq 2 ) { - # Seems to be fine :-) - } else { - throw "PowerShell Core does not seem to be installed or found" - } - } catch { + If ( $isPsCoreInstalled -eq $false ) { throw "PowerShell Core does not seem to be installed or found" } @@ -308,26 +296,6 @@ try { # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json $j = . $s.psCoreExePath -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" - # Check for warnings and errors - $j | ForEach-Object { - $jrow = $_ - Switch -Wildcard ( $jrow ) { - - "INFO*" { - Write-Information -MessageData $jrow -Tags @("Info") -InformationAction Continue - } - - "WARNING*" { - Write-Warning -Message $jrow - } - - "WARNUNG*" { - Write-Warning -Message $jrow - } - - } - } - break } @@ -363,13 +331,16 @@ try { } # return - If ( $useJob -eq $true ) { - $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput - $return = $jobReturn.output + If ( $LASTEXITCODE -ne 0 ) { + $j + } else { + If ( $useJob -eq $true ) { + $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput + $return = $jobReturn.output + } + $return } - $return - } catch { diff --git a/AptecoPSFramework/boilerplate/getresponses.ps1 b/AptecoPSFramework/boilerplate/getresponses.ps1 index 4b35241..e90ff61 100644 --- a/AptecoPSFramework/boilerplate/getresponses.ps1 +++ b/AptecoPSFramework/boilerplate/getresponses.ps1 @@ -5,10 +5,6 @@ # ################################################ -# Param( -# [hashtable] $params -# ) - #----------------------------------------------- # DEBUG SWITCH @@ -17,23 +13,6 @@ $debug = $false -#----------------------------------------------- -# INPUT PARAMETERS, IF DEBUG IS TRUE -#----------------------------------------------- - -# if ( $debug -eq $true ) { - -# $params = [hashtable]@{ -# Password = 'ko' -# Username = 'ko' -# #scriptPath = 'C:\faststats\Scripts\cleverreach' -# settingsFile = '.\settings.json' -# #mode='taggingOnly' -# } - -# } - - ################################################ # # NOTES @@ -47,29 +26,6 @@ bla bla #> -################################################ -# -# SCRIPT ROOT -# -################################################ -<# -if ( $debug -eq $true ) { - - if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") { - $scriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition - } else { - $scriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) - } - - $params.scriptPath = $scriptPath - -} - -# Some local settings -$dir = $params.scriptPath -Set-Location $dir -#> - #----------------------------------------------- # ADD MODULE PATH, IF NOT PRESENT #----------------------------------------------- @@ -121,20 +77,14 @@ If ($debug -eq $true) { # SET DEBUG MODE #----------------------------------------------- -# Set-DebugMode -DebugMode $debug +Set-DebugMode -DebugMode $debug #----------------------------------------------- # SETTINGS #----------------------------------------------- -# Set the settings -<# -$settings = Get-settings -$settings.logfile = ".\file.log" -Set-Settings -PSCustom $settings -#> -Import-Settings -Path ".\settings.json" +Import-Settings -Path ".\inx.yaml" ################################################ @@ -143,21 +93,11 @@ Import-Settings -Path ".\settings.json" # ################################################ -# TODO [x] check if we need to make a try catch here -> not needed, if we use a combination like - -<# - $msg = "Temporary count of $( $mssqlResult ) is less than $( $rowsCount ) in the original export. Please check!" - Write-Log -Message $msg -Severity ERROR - throw [System.IO.InvalidDataException] $msg - -#> - #----------------------------------------------- # GET MESSAGES #----------------------------------------------- - # Added try/catch again because of extras.xml wrapper try { diff --git a/AptecoPSFramework/boilerplate/preview.ps1 b/AptecoPSFramework/boilerplate/preview.ps1 index f7986f1..35f6791 100644 --- a/AptecoPSFramework/boilerplate/preview.ps1 +++ b/AptecoPSFramework/boilerplate/preview.ps1 @@ -9,21 +9,25 @@ Param( [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] - [hashtable]$params = [Hashtable]@{}, + [hashtable]$params = [Hashtable]@{} - [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] - [String]$jsonParams = "" + #,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] + #[String]$JsonParams = "" -) + ,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$JobId = "" -# If this script is called by itself, re-transform the escaped json string input back into a hashtable -If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params = [Hashtable]@{} - ( $jsonParams.replace("'",'"') | convertfrom-json ).psobject.properties | ForEach-Object { - Write-verbose "$( $_.Name ) - $( $_.Value )" - $params[$_.Name] = $_.Value - } -} + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$SettingsFile = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$ProcessId = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] + [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$DebugMode = "false" # This is a string, because when sent trough multiple processes, only text can be transferred instead of native objects + +) #----------------------------------------------- @@ -32,6 +36,12 @@ If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { $debug = $false +If ( $DebugMode -eq "true" ) { + $debug = $true +} +# TODO make an example lie +# . ./upload.ps -JobId 123 -DebugMode + #----------------------------------------------- # ADD MODULE PATH, IF NOT PRESENT @@ -67,7 +77,8 @@ $Env:Path = ( $scriptPath | Sort-Object -unique ) -join ";" # INPUT PARAMETERS, IF DEBUG IS TRUE #----------------------------------------------- -if ( $debug -eq $true -and $jsonParams -eq "" ) { +if ( $debug -eq $true ) { + $params = [hashtable]@{ # Automatic parameters @@ -81,95 +92,69 @@ if ( $debug -eq $true -and $jsonParams -eq "" ) { # Integration parameters #Force64bit = "true" - settingsFile = '.\settings.json' + #ForceCore = "true" + #ForcePython = "true" + #UseJob = "true" + settingsFile = '.\inx.yaml' + } -} -#Write-Log -message "Got a file with these arguments: $( [Environment]::GetCommandLineArgs() )" -writeToHostToo $false + +} ################################################ # -# NOTES +# CHECKS # ################################################ -<# - -bla bla - -# TODO [x] encrypt the global db parameter -# TODO [ ] activate the clear log functionality +#----------------------------------------------- +# DEFAULT VALUES +#----------------------------------------------- -#> +$useJob = $false +$enforce64Bit = $false +$enforceCore = $false +$enforcePython = $false +$isPsCoreInstalled = $false -################################################ -# -# SCRIPT ROOT -# -################################################ -<# -if ( $debug -eq $true ) { +#----------------------------------------------- +# CHECK INPUT +#----------------------------------------------- - if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") { - $scriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition +If ( $PsCmdlet.ParameterSetName -eq "JobIdInput" ) { + If ( $SettingsFile -eq "" ) { + throw "Please define a settings file" } else { - $scriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) + $settingsfileLocation = $SettingsFile + $useJob = $true } - - $params.scriptPath = $scriptPath - +} else { + $settingsfileLocation = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($params.settingsFile) } -# Some local settings -$dir = $params.scriptPath -Set-Location $dir -#> - -# Set current location to the settings files directory -$settingsFile = Get-Item $params.settingsFile -Set-Location $settingsFile.DirectoryName - - -################################################ -# -# 64 BIT CHECK -# -################################################ - -$thisScript = ".\preview.ps1" - #----------------------------------------------- -# CHECK IF 64 BIT SHOULD BE ENFORCED +# CHECK THE MODE THAT SHOULD BE USED #----------------------------------------------- # Start this if 64 is needed to enforce when this process is 32 bit and system is able to handle it If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq $false -and [System.Environment]::Is64BitOperatingSystem -eq $true ) { + $enforce64Bit = $true + $useJob = $true +} - $markerGuid = [guid]::NewGuid().toString() - - try { - - # Input parameter must be a string and for json the double quotes need to be escaped - $params.Add("markerGuid", $markerGuid) - $paramInput = ( ConvertTo-Json $params -Compress -Depth 99 ).replace('"',"'") - - # This inputs a string into powershell exe at a virtual place "sysnative" - # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json - $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JsonParams $paramInput -InformationAction "Continue" - - } catch { - Exit 1 - } - - # Convert the PSCustomObject back to a hashtable - $markerRow = $j.IndexOf($markerGuid) - ( convertfrom-json $j[$markerRow+1].replace("'",'"') ) #.trim() - - Exit 0 +# When you want to use PSCore with 32bit, please change that path in the settings file +If ( $params.ForceCore -eq "true" ) { + $enforceCore = $true + $useJob = $true +} +If ( $params.ForcePython -eq "true" ) { + $enforcePython = $true + $useJob = $true } @@ -180,19 +165,23 @@ If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq ################################################ #----------------------------------------------- -# IMPORT MODULE +# CHANGE PATH #----------------------------------------------- -Import-Module "AptecoPSFramework" #-Verbose -#Import-Module EncryptCredential # Not needed later, if we don't encrypt here -#Set-ExecutionDirectory -Path $dir +# Set current location to the settings files directory +$settingsFileItem = Get-Item $settingsfileLocation +Set-Location $settingsFileItem.DirectoryName #----------------------------------------------- -# ADD MORE PLUGINS +# IMPORT MODULE #----------------------------------------------- -#Add-PluginFolder "D:\Scripts\CleverReach\Plugins" +If ($debug -eq $true) { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" -Verbose +} else { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" +} #----------------------------------------------- @@ -207,55 +196,167 @@ Set-DebugMode -DebugMode $debug #----------------------------------------------- # Set the settings -Import-Settings -Path $params.settingsFile +If ( $useJob -eq $true -and $ProcessId -ne "") { + Import-Settings -Path $settingsfileLocation -ProcessId $ProcessId +} else { + Import-Settings -Path $settingsfileLocation +} +# Get all settings +$s = Get-Settings -################################################ -# -# PROGRAM -# -################################################ +#----------------------------------------------- +# ADD JOB +#----------------------------------------------- -# TODO [x] check if we need to make a try catch here -> not needed, if we use a combination like +If ( $params.UseJob -eq "true" -or $useJob -eq $true -and $PsCmdlet.ParameterSetName -eq "HashtableInput") { -<# - $msg = "Temporary count of $( $mssqlResult ) is less than $( $rowsCount ) in the original export. Please check!" - Write-Log -Message $msg -Severity ERROR - throw [System.IO.InvalidDataException] $msg + # Create a new job + $jobId = Add-JobLog + $jobParams = [Hashtable]@{ + "JobId" = $JobId + #"Plugin" = $script:settings.plugin.guid + "InputParam" = $params + #"Status" = "Starting" + "DebugMode" = $debug + } + Update-JobLog @jobParams -or +} - Write-Log -Message "Failed to connect to SQLServer database" -Severity ERROR - Write-Log -Message $_.Exception -Severity ERROR - throw $_ -#> +#----------------------------------------------- +# FIND OUT ABOUT PS CORE +#----------------------------------------------- +$calc = . $s.psCoreExePath { 1+1 } +if ( $calc -eq 2 ) { + $isPsCoreInstalled = $true +} + +#----------------------------------------------- +# FIND OUT THE MODE +#----------------------------------------------- + +$mode = "function" +If ( $enforce64Bit -eq $true ) { + $mode = "PSWin64" +} elseif ( $enforceCore -eq $true ) { + $mode = "PSCore" +} elseif ( $enforcePython -eq $true ) { + $mode = "Python" +} + + +################################################ +# +# PROGRAM +# +################################################ #----------------------------------------------- # CALL UPLOAD #----------------------------------------------- +$thisScript = ".\preview.ps1" + + # Added try/catch again because of extras.xml wrapper try { # Do the upload - $return = Show-Preview $params + Switch ( $mode ) { + + "function" { + + If ( $useJob -eq $true ) { + Show-Preview -JobId $jobId + } else { + $return = Show-Preview -InputHashtable $params + } - # Return the values, if succeeded - If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params.markerGuid # Output a guid to find out the separator - ( ConvertTo-Json $return -Depth 99 -Compress ).replace('"',"'") # output the result as json + break + } + + + "PSWin64" { + + # This inputs a string into powershell exe at a virtual place "sysnative" + $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + + } + + + "PSCore" { + + # Check if ps core is installed + If ( $isPsCoreInstalled -eq $false ) { + throw "PowerShell Core does not seem to be installed or found" + } + + # This inputs a string into powershell exe at a virtual place "sysnative" + # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json + $j = . $s.psCoreExePath -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + } + + + "Python" { + + <# + + assuming you have a python file like add.py and this content + + ```Python + import sys + + # This program adds two numbers + num1 = float(sys.argv[1]) + num2 = 6.3 + + # Add two numbers + sum = num1 + num2 + + # Display the sum + print('The sum of {0} and {1} is {2}'.format(num1, num2, sum)) + ``` + + #> + + # Then it can be called like this + . $s.pythonPath add.py "5.5" + + break + } + + } + + # return + If ( $LASTEXITCODE -ne 0 ) { + $j } else { + If ( $useJob -eq $true ) { + $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput + $return = $jobReturn.output + } $return } + } catch { throw $_ Exit 1 -} +} finally { + # Close the connection to joblog + If ( $useJob -eq $true ) { + Close-JobLogDatabase + } +} diff --git a/AptecoPSFramework/boilerplate/test.ps1 b/AptecoPSFramework/boilerplate/test.ps1 index 4a05a06..9600026 100644 --- a/AptecoPSFramework/boilerplate/test.ps1 +++ b/AptecoPSFramework/boilerplate/test.ps1 @@ -9,21 +9,25 @@ Param( [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] - [hashtable]$params = [Hashtable]@{}, + [hashtable]$params = [Hashtable]@{} - [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] - [String]$jsonParams = "" + #,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] + #[String]$JsonParams = "" -) + ,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$JobId = "" -# If this script is called by itself, re-transform the escaped json string input back into a hashtable -If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params = [Hashtable]@{} - ( $jsonParams.replace("'",'"') | convertfrom-json ).psobject.properties | ForEach-Object { - Write-verbose "$( $_.Name ) - $( $_.Value )" - $params[$_.Name] = $_.Value - } -} + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$SettingsFile = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$ProcessId = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] + [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$DebugMode = "false" # This is a string, because when sent trough multiple processes, only text can be transferred instead of native objects + +) #----------------------------------------------- @@ -32,6 +36,12 @@ If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { $debug = $false +If ( $DebugMode -eq "true" ) { + $debug = $true +} +# TODO make an example lie +# . ./upload.ps -JobId 123 -DebugMode + #----------------------------------------------- # ADD MODULE PATH, IF NOT PRESENT @@ -67,7 +77,8 @@ $Env:Path = ( $scriptPath | Sort-Object -unique ) -join ";" # INPUT PARAMETERS, IF DEBUG IS TRUE #----------------------------------------------- -if ( $debug -eq $true -and $jsonParams -eq "" ) { +if ( $debug -eq $true ) { + $params = [hashtable]@{ # Automatic parameters @@ -81,96 +92,67 @@ if ( $debug -eq $true -and $jsonParams -eq "" ) { # Integration parameters #Force64bit = "true" - settingsFile = '.\settings.json' + #ForceCore = "true" + #ForcePython = "true" + settingsFile = '.\inx.yaml' } -} -#Write-Log -message "Got a file with these arguments: $( [Environment]::GetCommandLineArgs() )" -writeToHostToo $false +} ################################################ # -# NOTES +# CHECKS # ################################################ -<# - -bla bla - -# TODO [x] encrypt the global db parameter -# TODO [ ] activate the clear log functionality +#----------------------------------------------- +# DEFAULT VALUES +#----------------------------------------------- -#> +$useJob = $false +$enforce64Bit = $false +$enforceCore = $false +$enforcePython = $false +$isPsCoreInstalled = $false -################################################ -# -# SCRIPT ROOT -# -################################################ -<# -if ( $debug -eq $true ) { +#----------------------------------------------- +# CHECK INPUT +#----------------------------------------------- - if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") { - $scriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition +If ( $PsCmdlet.ParameterSetName -eq "JobIdInput" ) { + If ( $SettingsFile -eq "" ) { + throw "Please define a settings file" } else { - $scriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) + $settingsfileLocation = $SettingsFile + $useJob = $true } - - $params.scriptPath = $scriptPath - +} else { + $settingsfileLocation = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($params.settingsFile) } -# Some local settings -$dir = $params.scriptPath -Set-Location $dir -#> - -# Set current location to the settings files directory -$settingsFile = Get-Item $params.settingsFile -Set-Location $settingsFile.DirectoryName - - -################################################ -# -# 64 BIT CHECK -# -################################################ - -$thisScript = ".\test.ps1" - #----------------------------------------------- -# CHECK IF 64 BIT SHOULD BE ENFORCED +# CHECK THE MODE THAT SHOULD BE USED #----------------------------------------------- # Start this if 64 is needed to enforce when this process is 32 bit and system is able to handle it If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq $false -and [System.Environment]::Is64BitOperatingSystem -eq $true ) { + $enforce64Bit = $true + $useJob = $true +} - $markerGuid = [guid]::NewGuid().toString() - - try { - - # Input parameter must be a string and for json the double quotes need to be escaped - $params.Add("markerGuid", $markerGuid) - $paramInput = ( ConvertTo-Json $params -Compress -Depth 99 ).replace('"',"'") - - # This inputs a string into powershell exe at a virtual place "sysnative" - # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json - $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JsonParams $paramInput -InformationAction "Continue" - - } catch { - Exit 1 - } - - # Convert the PSCustomObject back to a hashtable - $markerRow = $j.IndexOf($markerGuid) - ( convertfrom-json $j[$markerRow+1].replace("'",'"') ) #.trim() - - Exit 0 +# When you want to use PSCore with 32bit, please change that path in the settings file +If ( $params.ForceCore -eq "true" ) { + $enforceCore = $true + $useJob = $true +} +If ( $params.ForcePython -eq "true" ) { + $enforcePython = $true + $useJob = $true } @@ -181,21 +163,23 @@ If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq ################################################ #----------------------------------------------- -# IMPORT MODULE +# CHANGE PATH #----------------------------------------------- -If ($debug -eq $true) { - Import-Module "AptecoPSFramework" -Verbose -} else { - Import-Module "AptecoPSFramework" -} +# Set current location to the settings files directory +$settingsFileItem = Get-Item $settingsfileLocation +Set-Location $settingsFileItem.DirectoryName #----------------------------------------------- -# ADD MORE PLUGINS +# IMPORT MODULE #----------------------------------------------- -#Add-PluginFolder "D:\Scripts\CleverReach\Plugins" +If ($debug -eq $true) { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" -Verbose +} else { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" +} #----------------------------------------------- @@ -210,53 +194,167 @@ Set-DebugMode -DebugMode $debug #----------------------------------------------- # Set the settings -Import-Settings -Path $params.settingsFile +If ( $useJob -eq $true -and $ProcessId -ne "") { + Import-Settings -Path $settingsfileLocation -ProcessId $ProcessId +} else { + Import-Settings -Path $settingsfileLocation +} +# Get all settings +$s = Get-Settings -################################################ -# -# PROGRAM -# -################################################ +#----------------------------------------------- +# ADD JOB +#----------------------------------------------- -# TODO [x] check if we need to make a try catch here -> not needed, if we use a combination like +If ( $params.UseJob -eq "true" -or $useJob -eq $true -and $PsCmdlet.ParameterSetName -eq "HashtableInput") { -<# - $msg = "Temporary count of $( $mssqlResult ) is less than $( $rowsCount ) in the original export. Please check!" - Write-Log -Message $msg -Severity ERROR - throw [System.IO.InvalidDataException] $msg + # Create a new job + $jobId = Add-JobLog + $jobParams = [Hashtable]@{ + "JobId" = $JobId + #"Plugin" = $script:settings.plugin.guid + "InputParam" = $params + #"Status" = "Starting" + "DebugMode" = $debug + } + Update-JobLog @jobParams -or +} - Write-Log -Message "Failed to connect to SQLServer database" -Severity ERROR - Write-Log -Message $_.Exception -Severity ERROR - throw $_ -#> +#----------------------------------------------- +# FIND OUT ABOUT PS CORE +#----------------------------------------------- +$calc = . $s.psCoreExePath { 1+1 } +if ( $calc -eq 2 ) { + $isPsCoreInstalled = $true +} + +#----------------------------------------------- +# FIND OUT THE MODE +#----------------------------------------------- + +$mode = "function" +If ( $enforce64Bit -eq $true ) { + $mode = "PSWin64" +} elseif ( $enforceCore -eq $true ) { + $mode = "PSCore" +} elseif ( $enforcePython -eq $true ) { + $mode = "Python" +} + + +################################################ +# +# PROGRAM +# +################################################ #----------------------------------------------- # CALL UPLOAD #----------------------------------------------- +$thisScript = ".\test.ps1" + + # Added try/catch again because of extras.xml wrapper try { # Do the upload - $return = Test-Login $params + Switch ( $mode ) { + + "function" { - # Return the values, if succeeded - If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params.markerGuid # Output a guid to find out the separator - ( ConvertTo-Json $return -Depth 99 -Compress ).replace('"',"'") # output the result as json + If ( $useJob -eq $true ) { + Test-Login -JobId $jobId + } else { + $return = Test-Login -InputHashtable $params + } + + break + } + + + "PSWin64" { + + # This inputs a string into powershell exe at a virtual place "sysnative" + $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + + } + + + "PSCore" { + + # Check if ps core is installed + If ( $isPsCoreInstalled -eq $false ) { + throw "PowerShell Core does not seem to be installed or found" + } + + # This inputs a string into powershell exe at a virtual place "sysnative" + # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json + $j = . $s.psCoreExePath -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + } + + + "Python" { + + <# + + assuming you have a python file like add.py and this content + + ```Python + import sys + + # This program adds two numbers + num1 = float(sys.argv[1]) + num2 = 6.3 + + # Add two numbers + sum = num1 + num2 + + # Display the sum + print('The sum of {0} and {1} is {2}'.format(num1, num2, sum)) + ``` + + #> + + # Then it can be called like this + . $s.pythonPath add.py "5.5" + + break + } + + } + + # return + If ( $LASTEXITCODE -ne 0 ) { + $j } else { + If ( $useJob -eq $true ) { + $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput + $return = $jobReturn.output + } $return } + } catch { throw $_ Exit 1 +} finally { + + # Close the connection to joblog + If ( $useJob -eq $true ) { + Close-JobLogDatabase + } + } diff --git a/AptecoPSFramework/boilerplate/testsend.ps1 b/AptecoPSFramework/boilerplate/testsend.ps1 index 3d63ba6..0522b75 100644 --- a/AptecoPSFramework/boilerplate/testsend.ps1 +++ b/AptecoPSFramework/boilerplate/testsend.ps1 @@ -9,21 +9,25 @@ Param( [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] - [hashtable]$params = [Hashtable]@{}, + [hashtable]$params = [Hashtable]@{} - [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] - [String]$jsonParams = "" + #,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JsonInput')] + #[String]$JsonParams = "" -) + ,[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$JobId = "" -# If this script is called by itself, re-transform the escaped json string input back into a hashtable -If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params = [Hashtable]@{} - ( $jsonParams.replace("'",'"') | convertfrom-json ).psobject.properties | ForEach-Object { - Write-verbose "$( $_.Name ) - $( $_.Value )" - $params[$_.Name] = $_.Value - } -} + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$SettingsFile = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$ProcessId = "" + + ,[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='HashtableInput')] + [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, ParameterSetName='JobIdInput')] + [String]$DebugMode = "false" # This is a string, because when sent trough multiple processes, only text can be transferred instead of native objects + +) #----------------------------------------------- @@ -32,6 +36,12 @@ If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { $debug = $false +If ( $DebugMode -eq "true" ) { + $debug = $true +} +# TODO make an example lie +# . ./upload.ps -JobId 123 -DebugMode + #----------------------------------------------- # ADD MODULE PATH, IF NOT PRESENT @@ -67,7 +77,8 @@ $Env:Path = ( $scriptPath | Sort-Object -unique ) -join ";" # INPUT PARAMETERS, IF DEBUG IS TRUE #----------------------------------------------- -if ( $debug -eq $true -and $jsonParams -eq "" ) { +if ( $debug -eq $true ) { + $params = [hashtable]@{ # Automatic parameters @@ -79,95 +90,71 @@ if ( $debug -eq $true -and $jsonParams -eq "" ) { mode = 'prepare' ListName = '' - # Integration parameters + # Integration Parameters #Force64bit = "true" - settingsFile = '.\settings.json' + #ForceCore = "true" + #ForcePython = "true" + #UseJob = "true" + settingsFile = '.\inx.yaml' } -} -#Write-Log -message "Got a file with these arguments: $( [Environment]::GetCommandLineArgs() )" -writeToHostToo $false + +} ################################################ # -# NOTES +# CHECKS # ################################################ -<# - -bla bla +#----------------------------------------------- +# DEFAULT VALUES +#----------------------------------------------- -#> +$useJob = $false +$enforce64Bit = $false +$enforceCore = $false +$enforcePython = $false +$isPsCoreInstalled = $false -################################################ -# -# SCRIPT ROOT -# -################################################ -<# -if ( $debug -eq $true ) { +#----------------------------------------------- +# CHECK INPUT +#----------------------------------------------- - if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") { - $scriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition +If ( $PsCmdlet.ParameterSetName -eq "JobIdInput" ) { + If ( $SettingsFile -eq "" ) { + throw "Please define a settings file" } else { - $scriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) + $settingsfileLocation = $SettingsFile + $useJob = $true } - - $params.scriptPath = $scriptPath - +} else { + $settingsfileLocation = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($params.settingsFile) } -# Some local settings -$dir = $params.scriptPath -Set-Location $dir -#> - -# Set current location to the settings files directory -$settingsFile = Get-Item $params.settingsFile -Set-Location $settingsFile.DirectoryName - - -################################################ -# -# 64 BIT CHECK -# -################################################ - -$thisScript = ".\testsend.ps1" - #----------------------------------------------- -# CHECK IF 64 BIT SHOULD BE ENFORCED +# CHECK THE MODE THAT SHOULD BE USED #----------------------------------------------- # Start this if 64 is needed to enforce when this process is 32 bit and system is able to handle it If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq $false -and [System.Environment]::Is64BitOperatingSystem -eq $true ) { + $enforce64Bit = $true + $useJob = $true +} - $markerGuid = [guid]::NewGuid().toString() - - try { - - # Input parameter must be a string and for json the double quotes need to be escaped - $params.Add("markerGuid", $markerGuid) - $paramInput = ( ConvertTo-Json $params -Compress -Depth 99 ).replace('"',"'") - - # This inputs a string into powershell exe at a virtual place "sysnative" - # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json - $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JsonParams $paramInput -InformationAction "Continue" - - } catch { - Exit 1 - } - - # Convert the PSCustomObject back to a hashtable - $markerRow = $j.IndexOf($markerGuid) - ( convertfrom-json $j[$markerRow+1].replace("'",'"') ) #.trim() - - Exit 0 +# When you want to use PSCore with 32bit, please change that path in the settings file +If ( $params.ForceCore -eq "true" ) { + $enforceCore = $true + $useJob = $true +} +If ( $params.ForcePython -eq "true" ) { + $enforcePython = $true + $useJob = $true } @@ -178,21 +165,23 @@ If ( $params.Force64bit -eq "true" -and [System.Environment]::Is64BitProcess -eq ################################################ #----------------------------------------------- -# IMPORT MODULE +# CHANGE PATH #----------------------------------------------- -If ($debug -eq $true) { - Import-Module "AptecoPSFramework" -Verbose -} else { - Import-Module "AptecoPSFramework" -} +# Set current location to the settings files directory +$settingsFileItem = Get-Item $settingsfileLocation +Set-Location $settingsFileItem.DirectoryName #----------------------------------------------- -# ADD MORE PLUGINS +# IMPORT MODULE #----------------------------------------------- -#Add-PluginFolder "D:\Scripts\CleverReach\Plugins" +If ($debug -eq $true) { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" -Verbose +} else { + Import-Module "C:\Users\Florian\Documents\GitHub\AptecoPSFramework\AptecoPSFramework" +} #----------------------------------------------- @@ -207,53 +196,167 @@ Set-DebugMode -DebugMode $debug #----------------------------------------------- # Set the settings -Import-Settings -Path $params.settingsFile +If ( $useJob -eq $true -and $ProcessId -ne "") { + Import-Settings -Path $settingsfileLocation -ProcessId $ProcessId +} else { + Import-Settings -Path $settingsfileLocation +} +# Get all settings +$s = Get-Settings -################################################ -# -# PROGRAM -# -################################################ +#----------------------------------------------- +# ADD JOB +#----------------------------------------------- -# TODO [x] check if we need to make a try catch here -> not needed, if we use a combination like +If ( $params.UseJob -eq "true" -or $useJob -eq $true -and $PsCmdlet.ParameterSetName -eq "HashtableInput") { -<# - $msg = "Temporary count of $( $mssqlResult ) is less than $( $rowsCount ) in the original export. Please check!" - Write-Log -Message $msg -Severity ERROR - throw [System.IO.InvalidDataException] $msg + # Create a new job + $jobId = Add-JobLog + $jobParams = [Hashtable]@{ + "JobId" = $JobId + #"Plugin" = $script:settings.plugin.guid + "InputParam" = $params + #"Status" = "Starting" + "DebugMode" = $debug + } + Update-JobLog @jobParams -or +} - Write-Log -Message "Failed to connect to SQLServer database" -Severity ERROR - Write-Log -Message $_.Exception -Severity ERROR - throw $_ -#> +#----------------------------------------------- +# FIND OUT ABOUT PS CORE +#----------------------------------------------- +$calc = . $s.psCoreExePath { 1+1 } +if ( $calc -eq 2 ) { + $isPsCoreInstalled = $true +} + +#----------------------------------------------- +# FIND OUT THE MODE +#----------------------------------------------- + +$mode = "function" +If ( $enforce64Bit -eq $true ) { + $mode = "PSWin64" +} elseif ( $enforceCore -eq $true ) { + $mode = "PSCore" +} elseif ( $enforcePython -eq $true ) { + $mode = "Python" +} + + +################################################ +# +# PROGRAM +# +################################################ #----------------------------------------------- # CALL UPLOAD #----------------------------------------------- +$thisScript = ".\testsend.ps1" + + # Added try/catch again because of extras.xml wrapper try { # Do the upload - $return = Test-Send $params + Switch ( $mode ) { + + "function" { - # Return the values, if succeeded - If ( $PsCmdlet.ParameterSetName -eq "JsonInput" ) { - $params.markerGuid # Output a guid to find out the separator - ( ConvertTo-Json $return -Depth 99 -Compress ).replace('"',"'") # output the result as json + If ( $useJob -eq $true ) { + Test-Send -JobId $jobId + } else { + $return = Test-Send -InputHashtable $params + } + + break + } + + + "PSWin64" { + + # This inputs a string into powershell exe at a virtual place "sysnative" + $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + + } + + + "PSCore" { + + # Check if ps core is installed + If ( $isPsCoreInstalled -eq $false ) { + throw "PowerShell Core does not seem to be installed or found" + } + + # This inputs a string into powershell exe at a virtual place "sysnative" + # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json + $j = . $s.psCoreExePath -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" + + break + } + + + "Python" { + + <# + + assuming you have a python file like add.py and this content + + ```Python + import sys + + # This program adds two numbers + num1 = float(sys.argv[1]) + num2 = 6.3 + + # Add two numbers + sum = num1 + num2 + + # Display the sum + print('The sum of {0} and {1} is {2}'.format(num1, num2, sum)) + ``` + + #> + + # Then it can be called like this + . $s.pythonPath add.py "5.5" + + break + } + + } + + # return + If ( $LASTEXITCODE -ne 0 ) { + $j } else { + If ( $useJob -eq $true ) { + $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput + $return = $jobReturn.output + } $return } + } catch { throw $_ Exit 1 +} finally { + + # Close the connection to joblog + If ( $useJob -eq $true ) { + Close-JobLogDatabase + } + } diff --git a/AptecoPSFramework/boilerplate/upload.ps1 b/AptecoPSFramework/boilerplate/upload.ps1 index 2319026..ddde15a 100644 --- a/AptecoPSFramework/boilerplate/upload.ps1 +++ b/AptecoPSFramework/boilerplate/upload.ps1 @@ -125,6 +125,7 @@ $useJob = $false $enforce64Bit = $false $enforceCore = $false $enforcePython = $false +$isPsCoreInstalled = $false #----------------------------------------------- @@ -232,6 +233,16 @@ If ( $params.UseJob -eq "true" -or $useJob -eq $true -and $PsCmdlet.ParameterSet } + +#----------------------------------------------- +# FIND OUT ABOUT PS CORE +#----------------------------------------------- + +$calc = . $s.psCoreExePath { 1+1 } +if ( $calc -eq 2 ) { + $isPsCoreInstalled = $true +} + #----------------------------------------------- # FIND OUT THE MODE #----------------------------------------------- @@ -282,26 +293,6 @@ try { # This inputs a string into powershell exe at a virtual place "sysnative" $j = . $Env:SystemRoot\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" - # Check for warnings and errors - $j | ForEach-Object { - $jrow = $_ - Switch -Wildcard ( $jrow ) { - - "INFO*" { - Write-Information -MessageData $jrow -Tags @("Info") -InformationAction Continue - } - - "WARNING*" { - Write-Warning -Message $jrow - } - - "WARNUNG*" { - Write-Warning -Message $jrow - } - - } - } - break } @@ -310,14 +301,7 @@ try { "PSCore" { # Check if ps core is installed - try { - $calc = . $s.psCoreExePath { 1+1 } - if ( $calc -eq 2 ) { - # Seems to be fine :-) - } else { - throw "PowerShell Core does not seem to be installed or found" - } - } catch { + If ( $isPsCoreInstalled -eq $false ) { throw "PowerShell Core does not seem to be installed or found" } @@ -325,26 +309,6 @@ try { # It starts a 64bit version of Windows PowerShell and executes itself with the same input, only encoded as escaped json $j = . $s.psCoreExePath -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -InputFormat text -OutputFormat text -File $thisScript -JobId $jobId -SettingsFile $settingsfileLocation -ProcessId ( Get-ProcessIdentifier ) -DebugMode:$debug.toString() -InformationAction "Continue" - # Check for warnings and errors - $j | ForEach-Object { - $jrow = $_ - Switch -Wildcard ( $jrow ) { - - "INFO*" { - Write-Information -MessageData $jrow -Tags @("Info") -InformationAction Continue - } - - "WARNING*" { - Write-Warning -Message $jrow - } - - "WARNUNG*" { - Write-Warning -Message $jrow - } - - } - } - break } @@ -380,13 +344,16 @@ try { } # return - If ( $useJob -eq $true ) { - $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput - $return = $jobReturn.output + If ( $LASTEXITCODE -ne 0 ) { + $j + } else { + If ( $useJob -eq $true ) { + $jobReturn = Get-JobLog -JobId $jobId -ConvertOutput + $return = $jobReturn.output + } + $return } - $return - } catch {