EulandaConnect.psm1
# ***************************************************************************** # EULANDA Software GmbH # Documentation: https://github.com/Eulanda/EulandaConnect # License: https://github.com/Eulanda/EulandaConnect/blob/master/License.md # ***************************************************************************** # ----------------------------------------------------------------------------- # Global values # ----------------------------------------------------------------------------- Set-StrictMode -version latest Add-Type -AssemblyName System.Windows.Forms | Out-Null # ----------------------------------------------------------------------------- # Global ado constants # ----------------------------------------------------------------------------- [long]$global:adCmdText = 1 [long]$global:adLockOptimistic = 3 [long]$global:adOpenKeyset = 1 [long]$global:adStateClosed = 0 [long]$global:adStateConnecting = 2 [long]$global:adStateExecuting = 4 [long]$global:adStateFetching = 8 [long]$global:adStateOpen = 1 [long]$global:adTimeout = 60*20 [long]$global:adUseClient = 3 # ----------------------------------------------------------------------------- # Global helper für Get-Conn functiom # ----------------------------------------------------------------------------- [bool]$global:adCloseOnExit = $false # ----------------------------------------------------------------------------- # Global MsgBox # ----------------------------------------------------------------------------- [int]$global:mbNone = 0 [int]$global:mbOk = [System.Windows.Forms.MessageBoxButtons]::OK [int]$global:mbOkCancel = [System.Windows.Forms.MessageBoxButtons]::OkCancel [int]$global:mbAbortRetryIgnore = [System.Windows.Forms.MessageBoxButtons]::AbortRetryIgnore [int]$global:mbYesNoCancel = [System.Windows.Forms.MessageBoxButtons]::YesNoCancel [int]$global:mbYesNo = [System.Windows.Forms.MessageBoxButtons]::YesNo [int]$global:mbRetryCancel = [System.Windows.Forms.MessageBoxButtons]::RetryCancel [int]$global:mbStop = [System.Windows.Forms.MessageBoxIcon]::Stop [int]$global:mbHand = [System.Windows.Forms.MessageBoxIcon]::Stop [int]$global:mbQuestion = [System.Windows.Forms.MessageBoxIcon]::Question [int]$global:mbWarning = [System.Windows.Forms.MessageBoxIcon]::Warning [int]$global:mbExclamation = [System.Windows.Forms.MessageBoxIcon]::Warning [int]$global:mbInfo = [System.Windows.Forms.MessageBoxIcon]::Information [int]$global:mbAsterisk = [System.Windows.Forms.MessageBoxIcon]::Information [int]$global:mbInformation = [System.Windows.Forms.MessageBoxIcon]::Information [int]$global:mbButton1 = [System.Windows.Forms.MessageBoxDefaultButton]::Button1 [int]$global:mbButton2 = [System.Windows.Forms.MessageBoxDefaultButton]::Button2 [int]$global:mbButton3 = [System.Windows.Forms.MessageBoxDefaultButton]::Button3 [int]$global:mbButton4 = [System.Windows.Forms.MessageBoxDefaultButton]::Button4 [int]$global:mbrOk = [System.Windows.Forms.DialogResult]::Ok [int]$global:mbrCancel = [System.Windows.Forms.DialogResult]::Cancel [int]$global:mbrYes = [System.Windows.Forms.DialogResult]::Yes [int]$global:mbrNo = [System.Windows.Forms.DialogResult]::No [int]$global:mbrAbort = [System.Windows.Forms.DialogResult]::Abort [int]$global:mbrRetry = [System.Windows.Forms.DialogResult]::Retry [int]$global:mbrIgnore = [System.Windows.Forms.DialogResult]::Ignore [int]$global:mbrTryAgain = [System.Windows.Forms.DialogResult]::TryAgain [int]$global:mbrContinue = [System.Windows.Forms.DialogResult]::Continue # ----------------------------------------------------------------------------- # Public functions # ----------------------------------------------------------------------------- function Approve-Signature { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$path ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $filename = [IO.Path]::GetFileNameWithoutExtension($path) $extension = [IO.Path]::GetExtension($path) $folder = [IO.Path]::GetDirectoryName($path) if ((! $folder) -or ($folder -eq '.')) { $folder= Get-Location } # If no path take the last folder if (! ($filename)) { if (! ($folder -in ".", ".\", "")) { $filename = Split-Path $folder -Leaf } } # if no extension take ps1, then psm1 then exe if (! ($extension)) { $extension= '.ps1' if (-not (Test-Path "$folder\$($filename)$($extension)" )) { $extension= '.psm1' if (-not (Test-Path "$folder\$($filename)$($extension)" )) { $extension= '.exe' if (-not (Test-Path "$folder\$($filename)$($extension)" )) { # Change back to .ps1 so that Resolve-Path can render # an exeption with the default extension $extension= '.ps1' } } } } [string]$signFile= Resolve-Path "$folder\$($filename)$($extension)" Write-Host "Signing file '$signFile'" -ForegroundColor Blue [string]$app= $signFile $Process = (Start-Process -NoNewWindow -FilePath $(Get-SignToolPath) -PassThru -Wait -ArgumentList "sign /tr http://timestamp.sectigo.com?td=sha256 /td sha256 /fd sha256 /a ""$app""") if ($Process.exitcode -ne 0) { throw "ERROR! Signing failed! $_" } } function Close-Delivery { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr if ($deliveryId) { $sql = @" SET NOCOUNT ON; DECLARE @DeliveryId int SET @DeliveryId = $deliveryId EXEC dbo.cn_lfBuchen @lf_id=@DeliveryId "@ } elseif ($deliveryNo) { $sql = @" SET NOCOUNT ON; DECLARE @DeliveryNo int SET @DeliveryNo = $deliveryNo EXEC dbo.cn_lfBuchen @lf_Nummer=@DeliveryNo "@ } else { throw "Neither a delivery note id is specified, nor a delivery note number. Function: $($myInvocation.MyCommand)" } try { $myConn.Execute($sql) | out-null } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } function Close-SalesOrder { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [ValidateRange("Positive")] [int]$salesOrderId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr $sql = @" SET NOCOUNT ON; DECLARE @SalesOrderId int SET @SalesOrderId = $salesOrderId EXEC dbo.cn_afBuchen @af_id=@SalesOrderId "@ try { $myConn.Execute($sql) | out-null } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } function Confirm-System { [CmdletBinding()] param( [switch]$administrator , [switch]$controlledFolderAccess , [switch]$memory , [switch]$drives , [switch]$network ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $result = New-Object System.Collections.ArrayList if ($administrator) { $item= [PSCustomObject]@{ Description = 'Administrative rights' Value = [string](Test-Administrator) } $result.Add($item) | Out-Null } if ($controlledFolderAccess) { $item= [PSCustomObject]@{ Description = 'Ransomware protection aktiv' Value = [bool](Get-MpPreference | Select-Object EnableControlledFolderAccess).toString() } $result.Add($item) | Out-Null } if ($memory) { $item= [PSCustomObject]@{ Description = 'Working memory (GB)' Value = [string]((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1GB ) } $result.Add($item) | Out-Null } if ($drives) { for ($i=0; $i -lt (Get-PsDrive -PsProvider FileSystem).count-1; $i++) { $item= [PSCustomObject]@{ Description = 'Drive free on ' + (Get-PsDrive -PsProvider FileSystem)[$i].Name + ' (GB)' Value = [string]([math]::Round((Get-PsDrive -PsProvider FileSystem)[$i].Free/1GB)) } $result.Add($item) | Out-Null } $status = wmic diskdrive get model,status for ($i=1; $i -lt $Status.count-1; $i++) { if ($status[$i].trim()) { $lastWord = ($status[$i].trim() -split " ")[-1] $lastSpaceIndex = $status[$i].trim().LastIndexOf(" ")-1 $diskModel= $status[$i].Substring(0, $lastSpaceIndex).trim() $item= [PSCustomObject]@{ Description = "S.M.A.R.T. ($diskModel)" Value = [string]$Lastword.trim() } $result.Add($item) | Out-Null } } } if ($network) { $gatewayIp = Get-GatewayIp $item= [PSCustomObject]@{ Description = "Gateway Ip" Value = [string]$gatewayIp } $result.Add($item) | Out-Null $gatewayName = Get-Hostname ($gatewayIp) $item= [PSCustomObject]@{ Description = "Gateway Name" Value = [string]$gatewayName } $result.Add($item) | Out-Null $localIp = Get-LocalIp $item= [PSCustomObject]@{ Description = "Local Ip" Value = [string]$localIp } $result.Add($item) | Out-Null $localSubnet= Get-Subnet -localIp $localIp $item= [PSCustomObject]@{ Description = "Local Subnet" Value = [string]$localSubnet } $result.Add($item) | Out-Null $cidr= Get-Cidr -subnet $localSubnet $item= [PSCustomObject]@{ Description = "Local CIDR" Value = [string]$cidr } $result.Add($item) | Out-Null $publicIp = Get-PublicIp $item= [PSCustomObject]@{ Description = "Public Ip" Value = [string]$publicIp } $result.Add($item) | Out-Null $maxHosts= Get-MaxHosts -cidr $cidr $item= [PSCustomObject]@{ Description = "Max possible Hosts" Value = [string]$maxHosts } $result.Add($item) | Out-Null $networkId= Get-NetworkId -ip $localIp -cidr $cidr $item= [PSCustomObject]@{ Description = "Network ID" Value = [string]$networkId } $result.Add($item) | Out-Null $firstIp= Get-FirstIp -networkId $networkId -cidr $cidr $item= [PSCustomObject]@{ Description = "First possible Ip" Value = [string]$firstIp } $result.Add($item) | Out-Null $lastIp= Get-LastIp -networkId $networkId -cidr $cidr $item= [PSCustomObject]@{ Description = "Last possible Ip" Value = [string]$lastIp } $result.Add($item) | Out-Null $broadcastIp= Get-BroadcastIp -networkId $networkId -cidr $cidr $item= [PSCustomObject]@{ Description = "Broadcast Ip" Value = [string]$broadcastIp } $result.Add($item) | Out-Null } Return $result } function Convert-Accent { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$value , [ValidateSet('none', 'upper', 'lower', 'capital')] [string]$strCase = 'none' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) # case sensitive $hash = New-Object hashtable $hash['ä']='ae' $hash['ö']='oe' $hash['ü']='ue' $hash['Ä']='Ae' $hash['Ö']='Oe' $hash['Ü']='Ue' $hash['ß']='ss' $hash['Å“']='oe' $hash['â']='a' $hash['à']='a' $hash['á']='a' $hash['ç']='c' $hash['ê']='e' $hash['è']='e' $hash['é']='e' $hash['ë']='e' $hash['î']='i' $hash['ì']='i' $hash['í']='i' $hash['ï']='i' $hash['ô']='o' $hash['ò']='o' $hash['ó']='o' $hash['û']='u' $hash['ù']='u' $hash['ú']='u' $hash['Â']='A' $hash['À']='A' $hash['Á']='A' $hash['Ê']='E' $hash['È']='E' $hash['É']='E' $hash['Î']='I' $hash['Ì']='I' $hash['Í']='I' $hash['Ô']='O' $hash['Ò']='O' $hash['Ó']='O' $hash['Û']='U' $hash['Ù']='U' $hash['Ú']='U' [string]$result = $value foreach ($item in $hash.GetEnumerator()) { $result = $result -creplace "$($item.key)", "$($item.value)" } switch ( $strCase.ToLower() ) { 'none' { } 'upper' { $value = $value.ToUpper() } 'lower' { $value = $value.ToLower() } 'capital' { $value = $value.Substring(0,1).ToUpper() + $value.Substring(1).ToLower() } } Return $result } function Convert-DataToXml { [CmdletBinding()] param( [Parameter(Mandatory=$true)] $data , [Parameter(Mandatory=$false)] [switch]$metadata , [Parameter(Mandatory=$false)] [ValidateSet('none', 'upper', 'lower','capital')] [string]$strCase = 'upper' , [Parameter(Mandatory=$false)] [string]$root = 'Root' , [Parameter(Mandatory=$false)] [string]$arrRoot = 'Records' , [Parameter(Mandatory=$false)] [string]$arrSubRoot = 'Record' , [Parameter(Mandatory=$false)] $writer , [Parameter(Mandatory=$false)] [int]$level ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($DebugPreference -eq "Continue") { $on = $true } else { $on = $false } $root = Convert-StringCase -value $root -strCase $strCase if ($level -eq 0) { if ($on) { Write-Host "BEGIN: $root (:$level)" -ForegroundColor Cyan } # On level=0 it is a good way to initialize the xmlWriter $encoding = [System.Text.Encoding]::UTF8 $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true $settings.IndentChars = " " $settings.Encoding = $encoding $stream = New-Object System.IO.MemoryStream $writer = [System.XML.XmlWriter]::Create($stream, $settings) # Start with the root node $writer.WriteStartDocument() $writer.WriteStartElement($root) if ($metadata) { $writer = Write-XmlMetadata -writer $writer -strCase $strCase } } if (($data -is [System.Collections.ArrayList]) -or ($data -is [System.Object[]])) { $nodeName = (Convert-StringCase -value ($arrRoot) -strCase $strCase) $writer.WriteStartElement($nodeName) if ($on) { Write-Host "ROOT.Array(max$($data.count)): $nodeName (:$level)" -ForegroundColor Red } for ($i=0; $i -lt $data.count; $i++) { $nodeName = (Convert-StringCase -value $arrSubRoot -strCase $strCase) $writer.WriteStartElement($nodeName) if ($on) { Write-Host "ROOT.Array($i): $nodeName (:$level)" -ForegroundColor Red } # $nodeName = (Convert-StringCase -value ($root+$plural) -strCase $strCase) if ($data[$i] -is [System.Collections.Specialized.OrderedDictionary]) { if ($on) { Write-Host "hash(max$($data[$i].count)): $nodeName (:$level+1)" -ForegroundColor blue } } Convert-DataToXml -data $data[$i] -root $nodeName -level ($level+1) -writer $writer -strCase $strCase -arrRoot $arrRoot -arrSubRoot $arrSubRoot $writer.WriteEndElement() } $writer.WriteEndElement() } else { foreach ($key in $data.Keys) { $value = $data[$key] if (($value -is [System.Collections.ArrayList]) -or ($value -is [System.Object[]])) { $nodeName = (Convert-StringCase -value ($key) -strCase $strCase) $writer.WriteStartElement($nodeName) if ($on) { Write-Host "array(max$($value.count)): $nodeName (:$level)" -ForegroundColor Red } for ($i=0; $i -lt $value.count; $i++) { $nodeName = (Convert-StringCase -value $arrSubRoot -strCase $strCase) $writer.WriteStartElement($nodeName) if ($on) { Write-Host "array($i): $nodeName (:$level)" -ForegroundColor Red } # $nodeName = (Convert-StringCase -value ($key+$plural) -strCase $strCase) if ($value[$i] -is [System.Collections.Specialized.OrderedDictionary]) { if ($on) { Write-Host "hash(max$($value[$i].count)): $nodeName (:$level+1)" -ForegroundColor blue } } Convert-DataToXml -data $value[$i] -root $nodeName -level ($level+1) -writer $writer -strCase $strCase -arrRoot $arrRoot -arrSubRoot $arrSubRoot $writer.WriteEndElement() } $writer.WriteEndElement() } elseif ($value -is [System.Collections.Hashtable]) { $nodeName = (Convert-StringCase -value ($key) -strCase $strCase) $writer.WriteStartElement($nodeName) if ($on) { Write-Host "hash(max$($value.count)): $nodeName (:$level)" -ForegroundColor blue } $nodeName = (Convert-StringCase -value ($key) -strCase $strCase) Convert-DataToXml -data $value -root $nodeName -level ($level+1) -writer $writer -strCase $strCase -arrRoot $arrRoot -arrSubRoot $arrSubRoot $writer.WriteEndElement() } elseif ($value -is [System.Collections.Specialized.OrderedDictionary]) { $nodeName = (Convert-StringCase -value ($key) -strCase $strCase) $writer.WriteStartElement($nodeName) Convert-DataToXml -data $value -root $nodeName -level ($level+1) -writer $writer -strCase $strCase -arrRoot $arrRoot -arrSubRoot $arrSubRoot $writer.WriteEndElement() } else { # hash values comes here like: System.Collections.Specialized.OrderedDictionary # Here we have the xml node data if ($null -eq $value) { $strValue= '' } else { if ($value.GetType().Name -eq 'DateTime') { $strValue = Convert-DateToIso -value $value -noTimeZone } else { $strValue = [string]$value } } $nodeName = (Convert-StringCase -value ($key) -strCase $strCase) $writer.WriteElementString($nodeName,$strValue) $spaces = Get-Spaces -count ($level * 4) if ($on) { Write-Host "$($spaces)$($nodeName) = '$strValue' (:$level)" -ForegroundColor Green } } } } # If the level is '0' when the function exits, # all recursions are done and the XmlWriter can be closed. if ($level -eq 0) { if ($on) { Write-Host "END: $root (:$level)" -ForegroundColor Cyan } $writer.WriteEndElement() $writer.WriteEndDocument() $writer.Flush() $writer.Close() # Transfer the content of the memory stream to # a string and then to a standard XML object $stream.Position = 0 $reader = New-Object System.IO.StreamReader($stream) $xmlString = $reader.ReadToEnd() [xml]$xml = $xmlString Return $xml } } function Convert-DateToIso { [CmdletBinding()] param( [Parameter(Mandatory = $true)] $value , [switch]$asUtc , [switch]$noTime , [switch]$noDate , [switch]$noTimeZone , [switch]$zeroTime , [switch]$noonTime ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($noTime) { [datetime]$date = [datetime]::new($value.Year, $value.Month, $value.Day, 12, 0, 0) if ($noTimeZone) { if ($asUtc) { [string]$result = $(Get-Date -Date $date.ToUniversalTime() -format "yyyy-MM-dd") } else { [string]$result = $(Get-Date -Date $date -format "yyyy-MM-dd") } } else { if ($asUtc) { [string]$result = $(Get-Date -Date $date.ToUniversalTime() -format "yyyy-MM-ddZ") } else { [string]$result = $(Get-Date -Date $date -format "yyyy-MM-dd.0zzz") } } } elseif ($noDate) { if ($noonTime) { [datetime]$date = [datetime]::new(1, 1, 1, 12, 0, 0) } elseif ($zeroTime) { [datetime]$date = [datetime]::new($value.Year, $value.Month, $value.Day, 0, 0, 0) } else { [datetime]$date = [datetime]::new(1, 1, 1, $value.Hour, $value.Minute, $value.Second) } if ($noTimeZone) { if ($asUtc) { [string]$result = $(Get-Date -Date $date.ToUniversalTime() -format "HH:mm:ss") } else { [string]$result = $(Get-Date -Date $date -format "HH:mm:ss") } } else { if ($asUtc) { [string]$result = $(Get-Date -Date $date.ToUniversalTime() -format "HH:mm:ss.0Z") } else { [string]$result = $(Get-Date -Date $date -format "HH:mm:ss.0zzz") } } } else { # time AND date if ($noonTime) { [datetime]$date = [datetime]::new($value.Year, $value.Month, $value.Day, 12, 0, 0) } elseif ($zeroTime) { [datetime]$date = [datetime]::new($value.Year, $value.Month, $value.Day, 0, 0, 0) } else { [datetime]$date = [datetime]::new($value.Year, $value.Month, $value.Day, $value.Hour, $value.Minute, $value.Second) } if ($noTimeZone) { if ($asUtc) { [string]$result = $(Get-Date -Date $date.ToUniversalTime() -format "yyyy-MM-ddTHH:mm:ss") } else { [string]$result = $(Get-Date -Date $date -format "yyyy-MM-ddTHH:mm:ss") } } else { if ($asUtc) { [string]$result = $(Get-Date -Date $date.ToUniversalTime() -format "yyyy-MM-ddTHH:mm:ssZ") } else { [string]$result = $(Get-Date -Date $date.ToUniversalTime() -format "yyyy-MM-ddTHH:mm:ss.0zzz") } } } Return $result } function Convert-ImageToBase64 { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [ValidateScript({ if($_) { if(!(Test-Path $_)) { throw "Image file '$_' did not exist!" } } return $true })] [string]$path ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $content = [System.IO.File]::ReadAllBytes($path) $base64 = [System.Convert]::ToBase64String($content) $extension = [System.IO.Path]::GetExtension($path).ToLower() switch ($extension) { ".jpg" { $mimeType = "image/jpeg" } ".jpeg" { $mimeType = "image/jpeg" } ".gif" { $mimeType = "image/gif" } ".png" { $mimeType = "image/png" } ".bmp" { $mimeType = "image/bmp" } ".ico" { $mimeType = "image/x-icon" } default { throw "Unknown image file type: $extension" } } $result = "data:$mimeType;base64,$base64" return $result } function Convert-Slugify { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$value , [ValidateSet('none', 'upper', 'lower', 'capital')] [string]$strCase = 'lower' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $regex = [System.Text.RegularExpressions.Regex] $result = convert-accent -value $value $result = $regex::Replace($result, "[^a-zA-Z0-9\s-]", "") $result = $regex::Replace($result, "\s+", " ").Trim() $result = $regex::Replace($result, "\s", '_') switch ( $strCase.ToLower() ) { 'none' { } 'upper' { $result = $result.ToUpper() } 'lower' { $result = $result.ToLower() } 'capital' { $result = $result.Substring(0,1).ToUpper() + $result.Substring(1).ToLower() } } return $result } Function Convert-StringCase { [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] [string]$value , [Parameter(Mandatory=$false)] [ValidateSet('none', 'upper', 'lower', 'capital')] [string]$strCase = 'none' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) switch ( $strCase.ToLower() ) { 'none' { return $value } 'upper' { return $value.ToUpper() } 'lower' { return $value.ToLower() } 'capital' { return $value.Substring(0,1).ToUpper() + $value.Substring(1).ToLower() } } } function Convert-SubnetToBitmask { [CmdletBinding()] param( [string]$subnet , [int]$cidr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if ((! $subnet) -and (! $Cidr)) { $subnet = Get-Subnet # get it fron local ip } if (! $cidr) { $cidr = Get-Cidr -subnet $subnet } $bitmask = ('1' * $cidr).PadRight(32, '0') } catch { $bitmask= [string]"0".PadRight(32, '0') } Return $bitmask } function ConvertTo-WrappedLines { [CmdletBinding()] param( [string]$text , [int]$width= 80 , [switch]$asString , [switch]$useCrLf ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) # standard arrays dont allow 'add' command $result = [System.Collections.ArrayList]@() # Normalize string delimiter to unix style $text = $text.replace("`r`n", "`n") # Delete all unnecessary empty lines and characters at the end of the last paragraph $text = $text.TrimEnd() # Each line break is a hard return, i.e. a paragraph [string[]]$paragraphs = $text -split "\n+" foreach ($paragraph in $paragraphs ) { [string[]]$rawWords = $paragraph -split "\s+" # Create a word list with words and make sure that no word is longer than 'width' $words = [System.Collections.ArrayList]@() foreach ($word in $rawWords ) { if ($word.Length -le $width) { $words.Add($word) | Out-Null } else { # if one word is longer then the width, split it [string[]]$wordparts = $word -split "(.{$width})" -ne '' foreach ($word in $wordparts) { $words.Add($word) | Out-Null } } } # Put as many words as possible in one line, but never longer than 'width' [int]$column = 0 [string]$line = "" foreach ($word in $words ) { $column += $word.Length + 1 if ($column -gt $width ) { $result.add($line.trim()) | Out-Null $column = $word.Length + 1 $line = "" } $line = "$line$($word) " } $result.add($line.trim()) | Out-Null } if ($asString) { if ($useCrLf) { [string]$result = $result -join "`r`n" } else { [string]$result = $result -join "`n" } } Return $result } function ConvertTo-WrappedLinesEdi { [CmdletBinding()] param( [string]$text , [int]$Width = 80 ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) # Standard arrays dont allow 'add' command $result = [System.Collections.ArrayList]@() # Normalize string delimiter to unix style $text = $text.replace("`r`n", "`n") # Delete all unnecessary empty lines and characters at the end of the last paragraph $text = $text.TrimEnd() # Each line break is a hard return, i.e. a paragraph [string[]]$paragraphs = $text -split "\n+" # Clear unnessecary spaces in each paragraph for ($i=0; $i -le $paragraphs.Count-1; $i++) { $paragraphs[$i] = $paragraphs[$i].Trim() } # Check if nativ lines match 2 lines and each line is less $width if (($paragraphs.count -eq 2) -and ($paragraphs[0].length -le $width) -and ($paragraphs[1].length -le $width)) { $al = $paragraphs[0] $a1 = $paragraphs[1] write-verbose "Two line meats the shema. Passed 1:1" } elseif (($paragraphs.count -eq 1) -and ($paragraphs[0].length -le $width) ) { write-verbose "First line meats the shema. Passed 1:1" $al = $paragraphs[0] $a1 = "" } else { # AT LEAST ONE LINE IS TOO LONG # Make one big line [string]$paragraph = $paragraphs -join (' ') # Clear double spaces $paragraph = $paragraph.Replace(' ', ' ') [string]$al = $paragraph.Substring(0,[System.Math]::Min($width, $paragraph.Length)) [string]$a1 = $paragraph.Substring([System.Math]::Min($width, $paragraph.Length)) # Only if there is text in A1, it could be better to make a new line wrapping if ($a1) { $punctuation = Get-PunctuationIdx $al [int]$maxPunctuation = $al.Length / 3 * 2 if (($punctuation -ne -1) -and ($punctuation -lt $maxPunctuation)) { # if we are loosing to much chars we are dividung after the last word [Int]$test = $al.lastIndexOf(' ') if ($test -gt $punctuation) { $punctuation = $test -1 } } if ($punctuation -ge 0) { $a1 = "$($al.Substring($punctuation+1))$a1" $a1 = $a1.Trim() if ($a1.Length -gt $width) { $a1 = "$($a1.Substring(0,$width-3))..." } $al = $al.Substring(0, $punctuation+1) } } } [string[]]$result = @() $result += $al.trim() $result += $a1.trim() return $result } Function Export-DeliveryToXml { [CmdletBinding()] param( [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [parameter(Mandatory=$true)] [ValidateScript({ switch ($PSItem[-1]) { '.' {Throw 'A valid filepath cannot end with a period.'} '\' {Throw 'A valid filepath cannot end with a backslash.'} {$PSItem -match '\s'} {Throw 'A valid filepath cannot end with a blank character.'} Default {$true} } })] [string]$path , [parameter(Mandatory=$false)] [string]$root = 'Eulanda' , [parameter(Mandatory=$false)] [string]$arrRoot = "Items" , [parameter(Mandatory=$false)] [string]$arrSubRoot = "Item" , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { [string[]]$sql= Get-DeliverySql -deliveryNo $deliveryNo -deliveryId $deliveryId [System.Object]$data = Get-DataFromSql -sql $sql -conn $myConn [xml]$xml = Convert-DataToXml -data $data -root $root -arrRoot $arrRoot -arrSubRoot $arrSubRoot $xml.save($path) } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } Function Export-StockToXml { [CmdletBinding()] param( [parameter(Mandatory=$true)] [ValidateScript({ switch ($PSItem[-1]) { '.' {Throw 'A valid filepath cannot end with a period.'} '\' {Throw 'A valid filepath cannot end with a backslash.'} {$PSItem -match '\s'} {Throw 'A valid filepath cannot end with a blank character.'} Default {$true} } })] [string]$path , [parameter(Mandatory=$false)] [string[]]$filter , [parameter(Mandatory=$false)] [string]$alias , [parameter(Mandatory=$false)] [int]$qtyStatic , [parameter(Mandatory=$false)] [string]$warehouse , [parameter(Mandatory=$false)] [switch]$legacy , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { if ((! $warehouse) -and (! $legacy)) { [string]$nodeName = 'LAGERLISTE' } else { [string]$nodeName = 'LAGER' } [string[]]$sql= Get-StockSql -filter $filter -alias $alias -qtyStatic $qtyStatic -warehouse $warehouse -legacy:$legacy [System.Object]$data = Get-DataFromSql -sql $sql -conn $myConn -arrRoot $nodeName [xml]$xml = Convert-DataToXml -data $data -metadata -root 'EULANDA' -arrRoot 'ARTIKELLISTE' -arrSubRoot 'ARTIKEL' $xml.save($path) } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } Function Find-MssqlBrowser { [CmdletBinding()] param( [string]$fromIp , [string]$toIp , [int]$port = 1434 , [int]$timeout = 300 ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $SqlInstances = New-Object System.Collections.ArrayList if ((! $toIp) -and ($fromIp)) { $result = Find-SqlBrowser -ip $fromIp -port $port -timeout $timeout $SqlInstances += $result } else { if (! $fromIp) { $fromIp = Get-FirstIp $toIp = Get-LastIp } [bool]$run = $true do { Write-Verbose $fromIp $result = Find-SqlBrowser -ip $fromIp -port $port -timeout $timeout $SqlInstances += $result if (($fromIp) -eq ($toIp)) { $run = $false } else { $fromIp = Get-NextIp -ip $fromIp } } while ($run) } Return $SqlInstances } function Format-Xml { param( [Parameter(Position=0, Mandatory=$true, ParameterSetName='Text')] [string]$text , [Parameter(Position=0, Mandatory=$true, ParameterSetName='Path')] [ValidateScript( { if ([string]::IsNullOrEmpty($_)) { return $true } else { (Test-Path $_ ) } }, ErrorMessage= "The file '{0}' does not exist or the path is incorrect!" )] [string]$pathIn , [Parameter(Position=1, Mandatory = $false)] [ValidateScript( { if ([string]::IsNullOrEmpty($_)) { return $true } else { Test-Path (Split-Path $_ -Parent) } }, ErrorMessage= "The path '{0}' does not exist!" )] [string]$pathOut ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($PSCmdlet.ParameterSetName -eq 'Path') { $text = Get-Content -Path $pathIn } # If no encoding exists (common with FoxNet), use a default encoding $p = $text.IndexOf("<?") if ($p -lt 0) { $text = ('<?xml version="1.0" encoding="UTF-8"?>' + $text) } [System.Collections.ArrayList]$data = New-Object System.Collections.ArrayList $data.Add($text -join "`n") | Out-Null [System.Xml.XmlDataDocument]$xml= New-Object System.Xml.XmlDataDocument $xml.LoadXml($data -join "`n") [System.IO.StringWriter]$strWriter= New-Object System.Io.Stringwriter [System.Xml.XmlTextWriter]$writer= New-Object System.Xml.XmlTextWriter($strWriter) $writer.Formatting = [System.Xml.Formatting]::Indented $xml.WriteContentTo($writer) if ($pathOut) { $strWriter.ToString() | Out-File -FilePath $pathOut -Encoding UTF8 } else { $strWriter.ToString() } } function Get-AddressId { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$match , [Parameter(Mandatory = $false)] [ValidateRange("Positive")] [int]$id , [Parameter(Mandatory = $false)] [switch]$like , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [int]$result = 0 if ($Id) { [string]$sqlFrag = "Id = $id" } elseif ($match) { if ($like) { [string]$sqlFrag = "Match like '$match%'" } else { [string]$sqlFrag = "Match = '$match'" } } else { throw "Neither a id is specified, nor an match! Function: $($myInvocation.MyCommand)" } try { [string]$sql = "SELECT Id FROM Adresse WHERE $sqlFrag" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { [int]$result = $rs.fields('Id').Value if ($rs.RecordCount -gt 1) { throw "The search value '$sqlFrag' gives more then one result! " +` "Function: $($myInvocation.MyCommand)" } } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function Get-AdoRs { [CmdletBinding()] param( [parameter(Mandatory=$true)] $recordset ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($recordset) { # Toggle all record sets until you find an open one Do { If ($recordset.State -ne $global:adStateOpen) { $recordset = $recordset.NextRecordset() } } until ( (! $recordset) -or ($recordset.State -eq $global:adStateOpen) ) if ($recordset) { if ($recordset.eof) { $recordset= $null } } } Return $recordset } function Get-ArticleId { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$barcode , [Parameter(Mandatory = $false)] [string]$articleNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [int]$result = 0 try { if ($barcode) { [string]$sqlFrag = "Barcode = '$barcode'" } elseif ($articleNo) { [string]$sqlFrag = "ArtNummer = '$articleNo'" } else { throw "Neither a barcode is specified, nor a article number! Function: $($myInvocation.MyCommand)" } [string]$sql = "SELECT Id FROM Artikel WHERE $sqlFrag" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { $result = $rs.fields('Id').Value } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function Get-ArticleNo { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$barcode , [Parameter(Mandatory = $false)] [ValidateRange("Positive")] [int]$articleId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [string]$result = "" try { if ($barcode) { [string]$sqlFrag = "Barcode = '$barcode'" } elseif ($articleId) { [string]$sqlFrag = "Id = $articleId" } else { throw "Neither a barcode is specified, nor a article id! Function: $($myInvocation.MyCommand)" } $sql = "SELECT ArtNummer FROM Artikel WHERE $sqlFrag" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { $result = $rs.fields('ArtNummer').Value } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function Get-ArticlePackingUnit { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [Int]$articleId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [int]$result = 1 # Default packing unit is 1 try { [string]$sql = "SELECT VerpackEH [PackingUnit] FROM Artikel WHERE Id = $articleId" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { [int]$result = $rs.fields('PackingUnit').Value } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function Get-ArticleSql { [CmdletBinding()] param( [parameter(Position = 0, Mandatory=$false)] [ValidateScript({ if ($_ -eq "") { throw "Parameter 'select' cannot be an empty string!" } return $true })] [string]$select= '*' , [parameter(Position = 1, Mandatory=$false)] [string[]]$filter , [parameter(Position = 2, Mandatory=$false)] [string]$order= $alias , [Parameter(Position = 3, Mandatory=$false)] [ValidateSet('none', 'upper', 'lower', 'capital')] [string]$strCase = 'none' , [parameter(Position = 4, Mandatory=$false)] [ValidateSet('Id', 'Uid', 'ArtNummer', 'Barcode', IgnoreCase = $true)] [string]$alias = 'ArtNummer' , [parameter(Mandatory=$false)] [switch]$noIdAlias , [parameter(Mandatory=$false)] [ValidateRange(0, [int]::MaxValue)] [Nullable[int]]$limit , [parameter(Mandatory=$false)] [switch]$reorder , [parameter(Mandatory=$false)] [switch]$revers ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($filter) { [string]$sqlFilter= "WHERE (NOT $alias IS NULL) AND $($filter -join(' AND ')) " } else { [string]$sqlFilter= 'WHERE (NOT $alias IS NULL)' } if ($order) { [string]$sqlOrder = "ORDER BY $order" } else { [string]$sqlOrder = '' } $sqlSelect = $select if ($sqlSelect -ne '*') { if (! ($SqlSelect.Contains($alias, [System.StringComparison]::InvariantCultureIgnoreCase))) { $sqlSelect = "$alias,$sqlSelect" } if ($order) { [string[]]$arrOrder = $order -split ',' for ($i=0; $i -lt $arrOrder.count-1; $i++) { # Delete ASC and DESC $arrOrder[$i] = $arrOrder[$i].Split(' ')[0] if ($SqlSelect.Contains($arrOrder[$i], [System.StringComparison]::InvariantCultureIgnoreCase)) { $arrOrder[$i] = '' } } $arrOrder = $arrOrder | Where-Object { $_ -ne "" } $fieldList = $arrOrder -join ',' if ($fieldList) { $sqlSelect = "$fieldlist,$SqlSelect" } } } if (! ($null -eq $limit)) { $sqlLimit = "TOP $limit" } else { $SqlLimit = '' } if ($revers) { $sqlRevers = 'DESC' } else { $sqlRevers = '' } $arrSelect = $sqlSelect -split ',' $arrSelect = $arrSelect | ForEach-Object { $_.Trim() } if ($reorder) { $arrSelect = $arrSelect | Sort-Object } $arrSelect = $arrSelect | ForEach-Object { Convert-StringCase -value $_ -strCase $strcase } $sqlSelect = $arrSelect -join ',' if (! ($noIdAlias)) { $sqlSelect = "$alias [ID.ALIAS], $sqlSelect" } [string]$sqlMaster = @" SELECT $sqlSelect FROM ( SELECT $sqlLimit /* KEYS */ Id, ArtNummer, IsNull(Barcode,'') [Barcode], [Uid], /* IDENTIFIER */ IsNull(ArtMatch,'') [ArtMatch], IsNull(ArtNummerErsatz,'') [ArtNummerErsatz], IsNull(ArtNummerHersteller,'') [ArtNummerHersteller], /* GROUPS */ IsNull(RabattGr,'') [RabattGr], IsNull(WarenGr,'') [WarenGr], IsNull(ErloesGr,'') [ErloesGr], VerpackEh, PreisEh, MengenEh, /* CURRENCY */ Waehrung, MwStGr, MwStSatz, EkNetto, IsNull(Ek2Netto,0.0)[Ek2Netto], BruttoFlg, Vk, VkNetto, VkBrutto, /* SHOP */ IsNull(ShopExportDatum,'1900-01-01') [ShopExportDatum], ShopFreigabeFlg, /* FLAGS */ AuslaufFlg, NeuFlg, SonderFlg, /* INTRASTAT */ IsNull(Upper(UrsprungsLand),'')[UrsprungsLand], IsNull(UrsprungsRegion,'') [UrsprungsRegion], IsNull(WarenNr,'') [WarenNr], /* DESCRIPTION */ IsNull(Ultrakurztext,'') [UltraKurztext], IsNull(Kurztext1,'') [Kurztext1], IsNull(Kurztext2,'') [Kurztext2], IsNull(Info,'') [Info], IsNull(Langtext,'') [Langtext], /* OTHER */ Gewicht, Volumen, IsNull(Warnung,'') [Warnung], IsNull(Lagerplatz,'') [Lagerplatz] FROM Artikel $sqlFilter ) Dummy $sqlOrder $sqlRevers "@ Return [string[]]@($sqlMaster) } function Get-Bool { [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] [string]$boolStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $boolStr = $boolStr.ToUpper() if (($boolStr -eq "1") -or ($boolStr -eq "$TRUE") -or ($boolStr -eq "TRUE")) { [bool]$result = $true } else { [bool]$result = $false } Return $result } function Get-BroadcastIp { [CmdletBinding()] param( [string]$networkId , [string]$ip , [string]$subnet , [int]$cidr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if ((! $subnet) -and (! $cidr)) { $subnet = Get-Subnet # get it from localIp } if (! $networkId) { $networkId = Get-NetworkId -ip $ip -subnet $subnet -cidr $cidr } $maxHosts = Get-MaxHosts -subnet $subnet -cidr $cidr $broadcastIp = Get-NextIp -ip $networkId -inc ($maxHosts + 1) } catch { $broadcastIp= '0.0.0.0' } Return $broadcastIp } function Get-Cidr { [CmdletBinding()] param( [string]$subnet , [string]$ip ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if (! $subnet) { if (! $ip) { $ip= Get-LocalIp } $ipObj= [IPAddress]::Parse($ip) $cidr = (Get-NetIPAddress -AddressFamily IPv4 -IPAddress $ipObj -ErrorAction SilentlyContinue).PrefixLength } else { $subnetBytes = $subnet.Split('.') | ForEach-Object { [byte] $_ } $subnetBitString = [Convert]::ToString($subnetBytes[0], 2).PadLeft(8, '0') + ` [Convert]::ToString($subnetBytes[1], 2).PadLeft(8, '0') + ` [Convert]::ToString($subnetBytes[2], 2).PadLeft(8, '0') + ` [Convert]::ToString($subnetBytes[3], 2).PadLeft(8, '0') $cidr = $subnetBitString.Replace('0','').Length } } catch { $cidr= 0 } Return $cidr } function Get-Conn { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [long]$adStateClosed = 0 $global:adCloseOnExit = $false if ($conn) { $myConn = $conn if ($myConn.state -eq $adStateClosed) { $myConn.open() $global:adCloseOnExit = $true } } elseif ($udl) { $myConn = Get-ConnFromUdl -udl $udl $global:adCloseOnExit = $true } elseif ($connStr) { $myConn = Get-ConnFromStr $connStr $global:adCloseOnExit = $true } else { throw "Neither a ado connection object, or udl filename or an connection string is specified. Function: $($myInvocation.MyCommand)" } if ($global:adCloseOnExit) { # Avoid warning of vscode, because the variable is not used } Return $myConn } function Get-ConnItems { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { $params = $myConn.ConnectionString.Split(';') $conStrList = @{} foreach ($param in $params) { $key, $value = $param.Split('=') if (($key) -and ($value)) { $key = $key.trim() $value = $value.trim() $conStrList[$key] = $value } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $conStrList } function Get-ConnStr { [CmdletBinding()] param( [parameter(Mandatory=$true)] [string]$database , [parameter(Mandatory=$false)] [string]$server , [parameter(Mandatory=$false)] [string]$user , [parameter(Mandatory=$false)] [string]$password , [parameter(Mandatory=$false)] $conn , [ValidateScript({ if($_) { if(!(Test-Path $_)) { throw "UDL file '$_' did not exist!" } } return $true })] [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if (! ($server)) { $connItems = Get-ConnItems -conn $conn -udl $udl -connStr $connStr $server= $connItems['Data Source'] $user= $connItems['User ID'] $password= $connItems['Password'] } if (($user) -and ($password)) { [string]$connStr = ` "Provider=SQLOLEDB.1;Data Source=$server;Initial Catalog=$database;" +` "Persist Security Info=True;User ID=$user;Password=$password" } else { [string]$connStr = "Provider=SQLOLEDB.1;Data Source=$server;Initial Catalog=$database;Integrated Security=SSPI" } Return $connStr } function Get-DataFromSql { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string[]]$sql , [Parameter(Mandatory=$false)] [string]$arrRoot = 'Items' , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr $data = $null try { $data = New-Object System.Collections.ArrayList $rs = $Null $rs = $myConn.Execute($sql[0]) # Toggle all record sets until you find an open one Do { If ($rs.State -ne $global:adStateOpen) { $rs = $rs.NextRecordset() } } until ( (! $rs) -or ($rs.State -eq $global:adStateOpen) ) if ($rs) { while (! $rs.eof) { $record = [ordered]@{} for ($i=0; $i -lt $rs.fields.count; $i++) { $field = $rs.fields[$i] $record.add($field.name, $field.value) | Out-Null } if ($sql.Count -gt 1) { # Detail exists [string]$sqlTemp= $sql[1] if ($sql.Count -gt 2) { # Master / Detail Link exists [string]$sqlLink= $rs.fields[$sql[2]].value.replace("'","''") $sqlTemp = ($sqlTemp -f $sqlLink) } $record.add($arrRoot, (Get-DataFromSql -sql @($sqlTemp) -conn $myConn -udl $udl -connStr $connStr )) | Out-Null } $data.Add($record) | Out-Null $rs.MoveNext() | Out-Null } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $data } function Get-DeliveryId { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$deliveryNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [int]$deliveryId = 0 try { $rs = $Null [string]$sql = "SELECT Id [DeliveryId] FROM Lieferschein WHERE KopfNummer = $deliveryNo" $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { $deliveryId = $rs.fields('DeliveryId').value } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $deliveryId } function Get-DeliveryLink { [CmdletBinding()] Param ( [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] [string]$alias ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($alias) { $alias = "$alias." } if ($deliveryId) { [string]$result = "$($alias)Id = $deliveryId" } elseif ($deliveryNo) { [string]$result = "$($alias)KopfNummer = $deliveryNo" } else { throw "The delivery note cannot be loaded, either parameter DeliveryId or " +` "DeliveryNo must be specified. Function: $($myInvocation.MyCommand)" } Return [string]$result } function Get-DeliveryNo { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$deliveryId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [int]$deliveryNo = 0 try { $sql = "SELECT KopfNummer [DeliveryNo] FROM Lieferschein WHERE Id = $deliveryId" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { $deliveryNo = $rs.fields('DeliveryNo').value } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $deliveryNo } function Get-DeliveryQty { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$deliveryNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [long]$adUseClient = 3 [long]$adOpenKeyset = 1 [long]$adLockOptimistic = 3 [long]$adCmdText = 1 $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { [hashtable]$result = [ordered]@{} [string]$article = "" [float]$quantity = 0.0 # The barcode is being misused here as an article no. [string]$sql = @" SELECT Art.Barcode [Article], lfp.Menge [Quantity] FROM LieferscheinPos [lfp] JOIN Lieferschein [lf] ON lfp.KopfId = lf.id JOIN Artikel [art] ON art.Id = lfp.ArtikelId WHERE lf.KopfNummer = $deliveryNo ORDER BY lfp.PosNummer "@ $rs = $Null $rs = new-object -comObject ADODB.Recordset $rs.CursorLocation = $adUseClient $rs.Open($sql, $myConn, $adOpenKeyset, $adLockOptimistic, $adCmdText) if ($rs.eof) { throw "The delivery note '$deliveryNo' does not exist in EULANDA-ERP system. " +` "EULANDA DeliveryNo: $deliveryNo" } while (! $rs.eof) { [string]$article = $rs.fields('Article').value [float]$quantity = $rs.fields('Quantity').value # Under certain circumstances, the delivery note may contain the same article several times if (! $result.ContainsKey($article)) { $result.Add($article, $quantity) | Out-Null } else { $result.Item($article) += $quantity } $rs.MoveNext() | Out-Null } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function Get-DeliverySql { [CmdletBinding()] param( [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$sqlMaster = "SELECT Name1, Name2, Name3, Strasse [Street], Plz [Zip], " + ` "Ort [City], Provinz [Province], Land [Country], dbo.cnf_LfDruckAnschrift(Id) [Address], " + ` "FibuKonto [CustomerNo], " +` "Id [DeliveryId],KopfNummer [DeliveryNo], Datum [DeliveryDate], " + ` "af_id [SalesOrderId], af_Nummer [SalesOrderNo], af_Datum [SalesOrderDate], " + ` "Objekt [Reference], af_BestellNummer [CustomerOrderNo] " +` "FROM PRINT_Lieferschein WHERE $(Get-DeliveryLink -deliveryNo $deliveryNo -deliveryId $deliveryId) " [string]$sqlDetail = "SELECT lfp.PosNummer [Pos], lfp.Menge [Qty], art.Id [ArticleId], " + ` "art.ArtNummer [ArticleNo], " + ` "lfp.Langtext [Description], art.WarenNr [TradeNo], (lfp.Menge / lfp.VerpackEH) [Units], " + ` "CAST(((lfp.Menge + lfp.VerpackEH -1 ) / lfp.VerpackEH) AS int) [Boxes], art.Gewicht [Weight] " + ` "FROM LieferscheinPos [lfp] " + ` "JOIN Artikel [art] ON art.Id = lfp.ArtikelId " + ` "JOIN Lieferschein [lf] ON lf.Id = lfp.KopfId " + ` "WHERE $(Get-DeliveryLink -deliveryNo $deliveryNo -deliveryId $deliveryId -alias 'lf') " + ` "ORDER BY Pos" Return [string[]]@($sqlMaster,$sqlDetail) } function Get-DeliveryStatus { [CmdletBinding()] param ( [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr if ($deliveryId) { [string]$sqlFrag = "Id = $deliveryId" } elseif ($deliveryNo) { [string]$sqlFrag = "KopfNummer = $deliveryNo" } else { throw "Neither a delivery note id is specified, nor a delivery note number. Function: $($myInvocation.MyCommand)" } [int]$result = 0 try { [string]$sql = "SELECT Status FROM Lieferschein WHERE $sqlFrag" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { $result = $rs.fields('Status').value } else { $rs = $null } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } if (! $rs) { throw "The delivery note cannot be loaded! Sql: $sql" } Return $result } function Get-DesktopDir { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$desktopDir = [Environment]::GetFolderPath("Desktop") return $desktopDir } function Get-DmsFolderDelivery { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$dmsBaseFolder , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { if ($deliveryNo) { [string]$condition = "lf.KopfNummer = $deliveryNo" } elseif ($deliveryId) { [string]$condition = "lf.Id = $deliveryId" } else { throw "Delivery note could not be found because of missing parameter. Function $($myInvocation.MyCommand)" } [string]$match = "" [int]$deliveryNo = 0 [string]$sql = "SELECT ladr.Match [Match], lf.KopfNummer [DeliveryNo] FROM Lieferschein [lf] `r`n" +` "JOIN Adresse [ladr] ON lf.AdresseId = ladr.Id AND $condition" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { $match = $rs.fields('Match').value $deliveryNo = $rs.fields('DeliveryNo').value } } else { throw "Delivery note could not be found for condition '$condition'. Function: $($myInvocation.MyCommand)" } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } [string]$result = "$dmsBaseFolder\Adressen\$match\Lieferscheine\$deliveryNo" Return $result } function Get-DmsFolderSalesOrder { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$dmsBaseFolder , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$salesOrderNo , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$salesOrderId , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$customerOrderNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { if ($salesOrderId) { [string]$condition = "so.Id = $salesOrderId" } elseif ($salesOrderNo) { [string]$condition = "so.KopfNummer = $salesOrderNo" } elseif ($customerOrderNo) { [string]$condition = "so.Bestellnummer = '$customerOrderNo'" } else { throw "Sales order could not be found because of missing parameter. Function: $($myInvocation.MyCommand)" } [string]$match = "" [int]$salesOrderNo = 0 [string]$sql = "SELECT radr.Match [Match], so.KopfNummer [SalesOrderNo] FROM Auftrag [so] `r`n" +` "JOIN Adresse [radr] ON so.AdresseId = radr.Id AND $condition" $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { $match = $rs.fields('Match').value $salesOrderNo = $rs.fields('SalesOrderNo').value } } else { throw "Delivery note could not be found for condition '$condition'. Function: $($myInvocation.MyCommand)" } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } [string]$result = "$dmsBaseFolder\Adressen\$match\Aufträge\$salesOrderNo" Return $result } function Get-FieldTruncated { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] $rs , [Parameter(Mandatory = $true)] [string]$fieldName , [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$maxLen ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$Value = $rs.fields($fieldName).Value $value = $value.Trim() $value = $value.Substring(0, [System.Math]::Min($maxLen, $value.Length)) $value = $value.Trim() Return $value } function Get-Filename { [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] [ValidateScript({ switch ($PSItem[-1]) { '.' {Throw 'A valid filepath cannot end with a period.'} '\' {Throw 'A valid filepath cannot end with a backslash.'} {$PSItem -match '\s'} {Throw 'A valid filepath cannot end with a blank character.'} Default {$true} } })] [string]$path ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) Return [string]((Split-Path -Path $path -Leaf).Split(".")[0] + '.' + (Split-Path -Path $path -Leaf).Split(".")[1]) } function Get-FirstIp { [CmdletBinding()] param( [string]$networkId , [string]$ip , [string]$subnet , [int]$cidr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if ((! $subnet) -and (! $Cidr)) { $subnet = Get-Subnet # get it from loacalIp } if (! $networkId) { $networkId = Get-NetworkId -ip $ip -subnet $subnet -cidr $cidr } $firstIp = Get-NextIp -ip $networkId } catch { $firstIp= '0.0.0.0' } Return $firstIp } function Get-GatewayIp { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { $gatewayIp= (Get-NetRoute -AddressFamily IPv4 | Where-Object DestinationPrefix -eq '0.0.0.0/0' | Select-Object NextHop).NextHop } catch { $gatewayIp='0.0.0.0' } Return $gatewayIp } function Get-Hostname { [CmdletBinding()] param( [string]$ip ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if (! $ip) { $ip= Get-LocalIp } $hostname= [System.Net.Dns]::GetHostByAddress($ip).Hostname } catch { $hostname= '' } Return $hostname } function Get-HtmlEncoded { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$taggedString ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $taggedString = $taggedString.replace('\r', '') $taggedString = $taggedString.replace('\n', '{br/}') # Replace <br> and <strong> tags with placeholders $taggedString = $taggedString -replace "`r", '' $taggedString = $taggedString -replace "`n", '{br/}' $taggedString = $taggedString -replace '<br>', '{br/}' $taggedString = $taggedString -replace '<br/>', '{br/}' $taggedString = $taggedString -replace '<br />', '{br/}' $taggedString = $taggedString -replace '<strong>', '{strong}' $taggedString = $taggedString -replace '</strong>', '{/strong}' $taggedString = $taggedString -replace '<b>', '{b}' $taggedString = $taggedString -replace '</b>', '{/b}' $taggedString = $taggedString -replace '<i>', '{i}' $taggedString = $taggedString -replace '</i>', '{/i}' $taggedString = $taggedString -replace '<h1>', '{h1}' $taggedString = $taggedString -replace '</h1>', '{/h1}' $taggedString = $taggedString -replace '<h2>', '{h2}' $taggedString = $taggedString -replace '</h2>', '{/h2}' $taggedString = $taggedString -replace '<h3>', '{h3}' $taggedString = $taggedString -replace '</h3>', '{/h3}' $taggedString = $taggedString -replace '<p>', '{p}' $taggedString = $taggedString -replace '</p>', '{/p}' $taggedString = $taggedString -replace '<pre>', '{pre}' $taggedString = $taggedString -replace '</pre>', '{/pre}' $taggedString = $taggedString -replace '<ul>', '{ul}' $taggedString = $taggedString -replace '</ul>', '{/ul}' $taggedString = $taggedString -replace '<ol>', '{ol}' $taggedString = $taggedString -replace '</ol>', '{/ol}' $taggedString = $taggedString -replace '<li>', '{li}' $taggedString = $taggedString -replace '</li>', '{/li}' # Encode the string [string]$taggedString = [System.Web.HttpUtility]::HtmlEncode($taggedString) # Replace the placeholders with the original tags $taggedString = $taggedString -replace '{br/}', '<br/>' $taggedString = $taggedString -replace '{strong}', '<strong>' $taggedString = $taggedString -replace '{/strong}', '</strong>' $taggedString = $taggedString -replace '{b}', '<b>' $taggedString = $taggedString -replace '{/b}', '</b>' $taggedString = $taggedString -replace '{i}', '<i>' $taggedString = $taggedString -replace '{/i}', '</i>' $taggedString = $taggedString -replace '{h1}', '<h1>' $taggedString = $taggedString -replace '{/h1}', '</h1>' $taggedString = $taggedString -replace '{h2}', '<h2>' $taggedString = $taggedString -replace '{/h2}', '</h2>' $taggedString = $taggedString -replace '{h3}', '<h3>' $taggedString = $taggedString -replace '{/h3}', '</h3>' $taggedString = $taggedString -replace '{p}', '<p>' $taggedString = $taggedString -replace '{/p}', '</p>' $taggedString = $taggedString -replace '{pre}', '<pre>' $taggedString = $taggedString -replace '{/pre}', '</pre>' $taggedString = $taggedString -replace '{ul}', '<ul>' $taggedString = $taggedString -replace '{/ul}', '</ul>' $taggedString = $taggedString -replace '{ol}', '<ol>' $taggedString = $taggedString -replace '{/ol}', '</ol>' $taggedString = $taggedString -replace '{li}', '<li>' $taggedString = $taggedString -replace '{/li}', '</li>' Return $taggedString } function Get-HtmlMetaData { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$description ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [hashtable]$metaData = @{ author="EULANDA Software GmbH - ERP-Systems - Germany" generator="Powershell $($PsVersiontable.GitCommitId) by function ConvertTo-Html" keywords="eulanda, erp, powershell, convertto-html, html" viewport="width=device-width, initial-scale=1.0" } if ($description) { $metaData.Add('description', $description) | Out-Null } return $metaData } function Get-HtmlStyle { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$style = @" <style> html { margin: 0 auto; max-width: 800px; } body { font-family: Arial, Helvetica, sans-serif; font-size: 14px; } h1 { font-family: Arial, Helvetica, sans-serif; color: #e68a00; font-size: 28px; } h2 { font-family: Arial, Helvetica, sans-serif; color: #000099; font-size: 16px; } h3 { font-family: Arial, Helvetica, sans-serif; font-size: 16px; } table { font-size: 12px; border: 0px; width: 600px; height: auto; font-family: Arial, Helvetica, sans-serif; } td { padding: 4px; margin: 0px; border: 0; vertical-align: top; } th { background: #395870; background: linear-gradient(#49708f, #293f50); color: #fff; font-size: 11px; text-transform: uppercase; padding: 10px 15px; vertical-align: middle; } tbody tr:nth-child(even) { background-color: #f0f0f2; } #CreationDate { font-family: Arial, Helvetica, sans-serif; color: #ff3300; font-size: 12px; } .StatusAttention { color: #ff0000; } .StatusNormal { color: #008000; } </style> "@ Return $style } function Get-IniBool { [CmdletBinding()] param( [string]$section , [string]$variable ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if (test-path variable:global:ini) { [string]$test = $global:ini[$section][$variable] Return Get-Bool -boolStr $test } else { Return $false } } function Get-LastIp { [CmdletBinding()] param( [string]$networkId , [string]$ip , [string]$subnet , [int]$cidr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if ((! $subnet) -and (! $Cidr)) { $subnet = Get-Subnet # get it from localIp } if (! $networkId) { $networkId = Get-NetworkId -ip $ip -subnet $subnet -cidr $cidr } $maxHosts = Get-MaxHosts -subnet $subnet -cidr $cidr $lastIp = Get-NextIp -ip $networkId -inc ($maxHosts) } catch { $lastIp= '0.0.0.0' } Return $lastIp } function Get-LocalIp { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { $gatewayIp= Get-GatewayIp $gatewayIpObj= [IPAddress]::Parse($gatewayIp) $localIp = "" [string[]]$localIps= (Get-NetIPAddress -AddressFamily IPV4 -PrefixOrigin DHCP,MANUAL).IpAddress foreach ($ip in $localIps) { $ipObj = [IPAddress]::Parse($ip) $subnetMask = Get-Subnet -localIp $ip $subnetMaskObj = [IPAddress]::Parse($subnetMask) if (($ipObj.Address -band $subnetMaskObj.Address) -eq ($gatewayIpObj.Address -band $subnetMaskObj.Address)) { $localIp = $ip break } } } catch { $localIp= '0.0.0.0' } Return $localIp } function Get-LogName { [CmdletBinding()] param( [string]$ident , [string]$dateMask = "yyyy-MM-dd--HH-mm-ss-fff" ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if (! $ident) {$ident = 'DEF'} if (! (test-path variable:global:startTime)) { $global:startTime = Get-Date } [string]$datePart = Get-Date -date $global:startTime -format $dateMask [string]$result = "LOG-$ident-$datePart.txt" Return $result } function Get-LoremIpsum { param( [int]$MinParagraphs = 1, [int]$MaxParagraphs = 5 ) $numParagraphs = Get-Random -Minimum $MinParagraphs -Maximum $MaxParagraphs for ($i = 1; $i -le $numParagraphs; $i++) { $Paragraph = "$(Get-RandomParagraph)" if (! $Paragraphs) { $Paragraphs = $Paragraph } else { $Paragraphs += "`r`n$Paragraph" } } return $Paragraphs.TrimEnd() } function Get-MaxHosts { [CmdletBinding()] param( [string]$subnet , [int]$cidr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ((! $subnet) -and (! $cidr)) { $subnet= Get-Subnet # get it from localIp } try { if (! $cidr) { $cidr = Get-Cidr -subnet $subnet } [int]$maxHosts = [math]::Pow(2,(32-$cidr)) - 2 } catch { [int]$maxHosts= 0 } Return $maxHosts } function Get-ModulePath { param ( [Parameter(Mandatory = $true)] [string]$module ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $moduleFile = (Get-Module $module).Path $modulePath = Split-Path $moduleFile return $modulePath } function Get-MssqlInstances { [CmdletBinding()] param( [switch]$show ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $regKey = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" $result = New-Object System.Collections.ArrayList try { foreach ($instance in (Get-Item -Path $regKey | Select-Object -ExpandProperty Property)) { $regKey = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instance\MSSQLServer\CurrentVersion" $version = (Get-ItemProperty -Path $regKey).CurrentVersion $regKeyCombi = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" $combi = (Get-ItemProperty -Path $regKeyCombi).$instance $regKeyCombi = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$combi\MSSQLServer" $backupPath = (Get-ItemProperty -Path $regKeyCombi).BackupDirectory $regKeyCombi = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$combi\Setup" $binnPath = (Get-ItemProperty -Path $regKeyCombi).SQLBinRoot $collation = (Get-ItemProperty -Path $regKeyCombi).Collation $patchLevel = (Get-ItemProperty -Path $regKeyCombi).PatchLevel $dataPath = "$((Get-ItemProperty -Path $regKeyCombi).SQLDataRoot)\DATA" $regKeyCombi = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$combi\MSSQLServer\SuperSocketNetLib\Tcp" $tcpIp = (Get-ItemProperty -Path $regKeyCombi).Enabled $regKeyCombi = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$combi\MSSQLServer\SuperSocketNetLib\Sm" $sharedMemory = (Get-ItemProperty -Path $regKeyCombi).Enabled $regKeyCombi = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$combi\MSSQLServer\SuperSocketNetLib\Np" $namedPipes = (Get-ItemProperty -Path $regKeyCombi).Enabled $pipeName = (Get-ItemProperty -Path $regKeyCombi).PipeName $sqlService = Get-Service -Name "MSSQL`$${instance}" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Status $browserService = Get-Service -Name "SQLBrowser" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Status [bool]$firewallChecked = $false [bool]$sqlBrowserRule= $false [bool]$sqlServerRule= $false try { $firewallBrowser= Get-NetFirewallPortFilter -ErrorAction Stop | Where-Object LocalPort -eq 1434 | Get-NetFirewallRule -ErrorAction Stop | Where-Object Enabled -eq True | Where-Object Direction -eq Inbound if ($firewallBrowser) { [bool]$sqlBrowserRule= $true } # No Exception, so it was checked [bool]$firewallChecked = $true } catch [Microsoft.Management.Infrastructure.CimException] { } try { $firewallSqlServer = Get-NetFirewallApplicationFilter -ErrorAction Stop | Where-Object Program -match "$($binnPath.Replace('\','\\'))\\sqlservr.exe" | Get-NetFirewallRule -ErrorAction Stop if ($firewallSqlServer) { [bool]$sqlServerRule= $true } # No Exception, so it was checked [bool]$firewallChecked = $true } catch [Microsoft.Management.Infrastructure.CimException] { } $mdfFiles = Get-ChildItem -Path "$dataPath\*.mdf" -Name | Sort-Object $filesResult = New-Object System.Collections.ArrayList foreach ($mdfFile in $mdfFiles) { $databaseName = [System.IO.Path]::GetFileNameWithoutExtension($mdfFile) $ldfFile = Get-ChildItem -Path "$dataPath\$databaseName*.ldf" -Name | Select-Object -First 1 if ($ldfFile) { $mdfFilePath = [System.IO.Path]::Combine($dataPath, $mdfFile) $mdfFileInfo = New-Object System.IO.FileInfo ([System.IO.Path]::Combine($dataPath, $mdfFile)) $ldfFileInfo = New-Object System.IO.FileInfo ([System.IO.Path]::Combine($dataPath, $ldfFile)) $databaseSize = [math]::Round(($mdfFileInfo.Length + $ldfFileInfo.Length) / 1MB, 2) $databaseLastModified = [System.IO.File]::GetLastWriteTime($mdfFilePath).ToString("yyyy-MM-dd HH:mm:ss") $tempFilesObj = [PSCustomObject]@{ MdfFile = [string]$mdfFile LdfFile = [string]$ldfFile MdfSize = [double]$mdfFileInfo.Length / 1MB LdfSize = [double]$ldfFileInfo.Length / 1MB TotalSize = [double]$databaseSize LastModified = [string]$databaseLastModified } $filesResult.Add($tempFilesObj) | Out-Null } } $tempObj = [PSCustomObject]@{ Instance = [string]$instance Version = [version]$version PatchLevel = [version]$patchLevel Collation = [string]$collation BinnPath = [string]$binnPath DataPath = [string]$dataPath BackupPath = [string]$BackupPath SqlService = [string]$sqlService BrowserService = [string]$browserService TcpIp = [boolean]$tcpIp SharedMemory = [boolean]$sharedMemory NamedPipes = [boolean]$namedPipes PipeName = [string]$pipeName FirewallChecked = [bool]$firewallChecked SqlBrowserRule = [bool]$sqlBrowserRule SqlServerRule = [bool]$sqlServerRule Files = [PSCustomObject]$filesResult } $result.Add($tempObj) | Out-Null } if ($show) { foreach ($item in $result) { Write-Host "SERVER SETTINGS FOR: [ $($item.Instance) ]" -ForegroundColor Yellow $item | Select-Object -Property Instance, Version, PatchLevel, Collation, BinnPath, DataPath, BackupPath, SqlService, BrowserService, NamedPipes, TcpIp, SharedMemory, FirewallChecked, SqlBrowserRule, SqlServerRule | Format-List | Out-Host Write-Host "DATABASE FILES FOR: [ $($item.Instance) ]" -ForegroundColor Blue Write-Host "Sizes are shown in MB" -ForegroundColor Blue $item.Files | Format-List | Out-Host } If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "Firewall rules was not to check, this requires administrator privileges. For this reason FirewallValid=False." -ForegroundColor Red } } } catch { if ($show) { Write-Host "$_" -ForegroundColor Red } } Return $result } function Get-MultipleOptions { [CmdletBinding()] Param ( [string]$values , [string[]]$list ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$newValues = '' if ($values) { [string[]]$valuesArray = $values.Split(',') foreach ($value in $valuesArray) { [int]$idx = $list.ToUpper().IndexOf($value.ToUpper()) if ($idx -eq -1 ) { [string]$item = $list[0] } else { [string]$item = $list[$idx] } if ($newValues) { $i = $newValues.ToUpper().IndexOf($item.ToUpper()) if ($i -eq -1) { [string]$newValues += (',' + $item) } } else { [string]$newValues = $Item } } $result = $newValues } else { [string]$result = $list[0] } Return $result } function Get-NetworkId { [CmdletBinding()] param( [string]$ip , [string]$subnet , [int]$cidr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if (! $ip) { $ip= Get-LocalIp $subnet= Get-Subnet -localIp $ip } $ipObj= [IpAddress]$ip if (! $subnet) { $subnet = Get-Subnet -cidr $cidr } $subnetObj= [IpAddress]$subnet $networkId = ([IpAddress]($ipObj.Address -band $subnetObj.Address)).IpAddressToString } catch { $networkId= '0.0.0.0' } Return $networkId } function Get-NextIp { [CmdletBinding()] param( [string]$ip , [int]$inc = 1 ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { $ipObj = [IPAddress]$ip $ipBytes = $ipObj.GetAddressBytes() [System.Array]::Reverse($ipBytes) $ipInt = [System.BitConverter]::ToUInt32($ipBytes, 0) $nextIpInt = $ipInt + $inc $nextIpBytes = [System.BitConverter]::GetBytes($nextIpInt) [System.Array]::Reverse($nextIpBytes) if ([IntPtr]::Size -eq 4) { # x86 $newIp = New-Object System.Net.IPAddress ([System.Array]::CreateInstance([byte], 4)) [System.Buffer]::BlockCopy($nextIpBytes, 0, $nextIp.GetAddressBytes(), 0, 4) } else { # x64 $newIp = New-Object System.Net.IPAddress -ArgumentList (,$nextIpBytes) } $newIpAddress= $newIp.IPAddressToString } catch { $newIpAddress= '0.0.0.0' } Return $newIpAddress } function Get-OldestFile { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$fileMask ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$path = "$fileMask" [string]$oldestFile = "" $entry = Get-ChildItem -Path $path | Sort-Object -Property LastWriteTime | select-object -First 1 if ($entry) { [string]$oldestFile = $entry.Name } Return $oldestFile } function Get-Path32 { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ( $($env:PROCESSOR_ARCHITECTURE) -eq "x86") { $Path32 = $($env:PROGRAMFILES) } else { $Path32 = $(${env:PROGRAMFILES(x86)}) } Return $Path32 } function Get-PublicIp { [CmdletBinding()] Param () Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $result = "" if (! $result) { try { $result = (Resolve-DnsName myip.opendns.com -Server resolver1.opendns.com -type A -ErrorAction SilentlyContinue).IPAddress } catch { } } if (! $result) { try { $html = Invoke-RestMethod https://checkip.eurodyndns.org $lines = $html.split("`n") foreach ($line in $lines) { $p = $Line.IndexOf("IP Address:") if ($p -gt 0) { $p = $line.IndexOf(":") if ($p -gt 0) { $result = $line.SubString($p +1).Trim() } } } } catch { } } if (! $result) { try { $result = Invoke-RestMethod https://ifconfig.me/ip } catch { } } if (! $result) { $result= '0.0.0.0' } return $result } function Get-ResStr { [CmdletBinding()] param ( [string]$Key ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if (!(test-path variable:global:resx)) { $global:userlang = [System.Threading.Thread]::CurrentThread.CurrentUICulture.Name if ($global:userlang.Substring(0,2) -eq 'de') {$global:userlang = 'de-DE'} if ($global:userlang.Substring(0,2) -eq 'en') {$global:userlang = 'en-US'} $global:resx = @{} [string]$path = (Get-Module -Name EulandaConnect | Select-Object -ExpandProperty Path) [string]$path = Split-path $path $xmlFiles = Get-ChildItem "$path\*.resx" foreach ($xmlFile in $xmlFiles) { $reslang = $xmlFile.Name.Split('.')[1] $xmlContent = Get-Content $xmlFile -Raw $xml = [xml]$xmlContent foreach ($data in $xml.root.data) { if ($resx[$data.name]) { $resx[$data.name][$reslang]= $data.value } else { $values = @{} $values[$reslang] =$data.value $resx[$data.name] = $values } } } } if ($resx.ContainsKey($key)) { if ($resx[$key].ContainsKey($userlang)) { $value = $resx[$Key][$userlang] } elseif ($resx[$key].ContainsKey('en-US')) { $value = $resx[$Key]['en-US'] } else { $value = "?[$userlang`:$key]" } } else { $value = "?[$key]" } return $value } function Get-ScriptDir { [CmdletBinding()] Param () Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$result = "" if (!(test-path variable:hostinvocation)) {$hostinvocation = $null} if ($null -ne $hostinvocation) { $result = (Split-Path $hostinvocation.MyCommand.path) } else { # scope 1 is the parent scope of the actual scope $invocation=(get-variable MyInvocation -Scope 1).Value if ($invocation.scriptname) { $result = (Split-Path $invocation.scriptname) } } if (-not (Test-Path $result)) { $result = $PSScriptRoot } if (-not (Test-Path $result)) { $result = (Get-Item -Path ".\" -Verbose).FullName} return $result } function Get-SftpNextFilename { [CmdletBinding()] Param( [parameter(Mandatory=$true)] [string]$server , [parameter(Mandatory=$false)] [int]$port= 22 , [parameter(Mandatory=$false)] [string]$user , [parameter(Mandatory=$false)] [string]$password , [parameter(Mandatory=$false)] [string]$remoteFolder , [parameter(Mandatory=$false)] [string]$fileMask , [parameter(Mandatory=$false)] [string]$comObject= 'IPWorksSSH.SFTP' , [parameter(Mandatory=$false)] [string]$license= '(you have to buy one license from n/software)' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$result = $null $sftp = New-SftpInstance -comObject $comObject $sftp.ok = $license $sftp.Config("SSHAcceptAnyServerHostKey=true") $sftp.SSHHost = $server $sftp.SSHPassword = $password $sftp.SSHAuthMode = 2 $sftp.SSHUser = $user $sftp.SSHPort = $port $sftp.SSHLogon($sftp.SSHHost, $sftp.SSHPort) try { $sftp.RemotePath = $remoteFolder $sftp.RemoteFile = $fileMask $sFtp.ListDirectory() write-verbose "DirListCount: $($sftp.DirListCount)" For ($i=0; $i -le $sftp.DirListCount-1; $i++) { if (! $sftp.DirListIsDir($i)) { [string]$result = $sftp.DirListFilename($i) break } } } finally { $sftp.SSHLogoff() } Return $result } function Get-SignToolPath { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $rootPath = "$(Get-Path32)\Windows Kits\10\bin\" $versionRegex = '^10\.\d+\.\d+\.\d+$' $folders = Get-ChildItem -Path $rootPath -Directory | Where-Object { $_.Name -match $versionRegex } $sortedFolders = $folders | Sort-Object -Property @{Expression = {[version] $_.Name}; Descending = $true} $newestFolder = $sortedFolders | Select-Object -First 1 $signtoolPath = Join-Path -Path $newestFolder.FullName -ChildPath 'x64\signtool.exe' if (Test-Path $signtoolPath) { Return $signtoolPath } else { throw "Signtool not found in expected Windows SDK folder '$rootPath'!" } } function Get-SingleOption { [CmdletBinding()] Param ( [string]$value , [string[]]$list ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [int]$idx = $list.ToUpper().IndexOf($value.ToUpper()) if ($idx -eq -1) { [string]$result = $list[0] } else { [string]$result = $list[$idx] } Return $result } function Get-Spaces { [CmdletBinding()] param( [int]$count ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) return ' ' * $count } function Get-StockSql { [CmdletBinding()] param( [parameter(Mandatory=$false)] [string[]]$filter , [parameter(Mandatory=$false)] [ValidateSet('ID', 'UID', 'ARTNUMMER', 'BARCODE', IgnoreCase = $true)] [string]$alias = 'ARTNUMMER' , [parameter(Mandatory=$false)] [int]$qtyStatic , [parameter(Mandatory=$false)] [string]$warehouse , [parameter(Mandatory=$false)] [switch]$legacy ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($filter) { [string]$sqlFilter= " AND $($filter -join(' AND ')) " } else { [string]$sqlFilter= '' } if ($warehouse) { # ----------------------------------------------------------------------------- # Only one warehouse # ----------------------------------------------------------------------------- # Master # ------------------------------------------ [string]$sqlMaster = @" SELECT CONVERT(VARCHAR(100),art.$alias) [ID.ALIAS] FROM [dbo].Lagerort lo JOIN [dbo].LagerKonto lk on lk.Lagerort = lo.id JOIN [dbo].Artikel [art] ON art.id = lk.artikelId AND art.ArtNummer not like '.MUSTER%' $sqlFilter WHERE lo.id >= 1000 AND lo.id < 1400 AND lk.IdentId IS NULL AND lk.PlatzId IS NULL AND lo.Bezeichnung = '$warehouse' ORDER BY 1 "@ # ------------------------------------------ # Detail # ------------------------------------------ if ($qtyStatic) { [string]$qty = $qtyStatic } else { [string]$qty = 'lk.Menge' } if ($legacy) { [string]$sqlLegacy= ", $qty [BESTANDVERFUEGBAR1], $qty [BESTANDVERFUEGBAR2]" } else { [string]$sqlLegacy = "" } [string]$sqlDetail = @" SELECT $qty [BESTANDVERFUEGBAR] $sqlLegacy FROM [dbo].Lagerort lo JOIN [dbo].LagerKonto lk on lk.Lagerort = lo.id JOIN [dbo].Artikel [art] ON art.$alias = '{0}' WHERE lk.ArtikelId = (SELECT TOP 1 Id FROM [dbo].Artikel WHERE $alias = '{0}') AND lk.IdentId IS NULL AND lk.PlatzId IS NULL AND lo.Bezeichnung = '$warehouse' "@ } elseif ($legacy) { # ----------------------------------------------------------------------------- # All warehouses with sales and purchase correction. Pur legacy support # ----------------------------------------------------------------------------- # Master # ------------------------------------------ [string]$sqlMaster = @" SELECT CONVERT(VARCHAR(100),art.$alias) [ID.ALIAS] FROM [dbo].Artikel [art] WHERE art.ArtNummer not like '.MUSTER%' $sqlFilter ORDER BY 1 "@ # ------------------------------------------ # Detail # ------------------------------------------ if ($qtyStatic) { [string]$qtyFields = ` "$qtyStatic [BestandVerfuegbar], " +` "$qtyStatic [BestandVerfuegbar1], " +` "$qtyStatic [BestandVerfuegbar2]" } else { [string]$qtyFields = ` "[dbo].[cnf_BestandVerfuegbarGesamt](art.Id,0) [BestandVerfuegbar], " +` "[dbo].[cnf_BestandVerfuegbar1](art.Id,0) [BestandVerfuegbar1], " +` "[dbo].[cnf_BestandVerfuegbar2](art.Id,0) [BestandVerfuegbar2]" } [string]$sqlDetail = @" -- Total inventory from all own warehouses with sales and purchase output fields SELECT $qtyFields FROM [dbo].Artikel [art] WHERE art.$alias = '{0}' "@ } else { # ----------------------------------------------------------------------------- # All warehouses , all suplier and totals with sales and purchase correction # ----------------------------------------------------------------------------- # Master # ------------------------------------------ [string]$sqlMaster = @" SELECT CONVERT(VARCHAR(100),art.$alias) [ID.ALIAS], art.Id [ID], CONVERT(varchar(36), art.Uid) [UID], art.ArtNummer [ARTNUMMER], art.Barcode [BARCODE], art.ChangeDate [CHANGEDATE], art.ShopFreigabeFlg [SHOPFREIGABEFLG], art.ShopExportDatum [SHOPEXPORTDATUM] FROM [dbo].Artikel [art] WHERE art.ArtNummer not like '.MUSTER%' $sqlFilter ORDER BY 1 "@ # ------------------------------------------ # Detail # ------------------------------------------ if ($qtyStatic) { $sqlStaticWarehouse = $qtyStatic $sql0 = $qtyStatic $sql1 = $qtyStatic $sql2 = $qtyStatic $sqlSupplier = $qtyStatic } else { $sqlStaticWarehouse = 'lk.Menge' $sql0 = '[dbo].[cnf_BestandVerfuegbarGesamt](art.Id,0)' $sql1 = '[dbo].[cnf_BestandVerfuegbar1](art.Id,0)' $sql2 = '[dbo].[cnf_BestandVerfuegbar2](art.Id,0)' $sqlSupplier = 'IsNull(kart.Bestand,0)' } [string]$sqlDetail = @" SELECT * FROM ( SELECT lo.id [KONTO], UPPER(lo.Bezeichnung) [BEZEICHNUNG], $sqlStaticWarehouse [MENGE] FROM [dbo].Lagerort lo JOIN [dbo].LagerKonto lk ON lk.Lagerort = lo.id JOIN [dbo].Artikel [art] ON art.$alias = '{0}' WHERE lo.id >= 1000 AND lo.id < 1400 AND lk.ArtikelId = (SELECT TOP 1 Id FROM [dbo].Artikel WHERE $alias = '{0}') AND lk.IdentId IS NULL AND lk.PlatzId IS NULL -- Total inventory from all own warehouses that is physically present UNION SELECT 10000+0 [KONTO], 'BESTANDVERFUEGBAR' [BEZEICHNUNG], $sql0 [MENGE] FROM [dbo].Artikel [art] WHERE art.$alias = '{0}' -- Total inventory from all own warehouses less sales orders UNION SELECT 10000+1 [KONTO], 'BESTANDVERFUEGBAR1' [BEZEICHNUNG], $sql1 [MENGE] FROM [dbo].Artikel [art] WHERE art.$alias = '{0}' -- Total inventory from all own warehouses less sales orders UNION SELECT 10000+1 [KONTO], 'BESTANDVERFUEGBAR2' [BEZEICHNUNG], $sql2 [MENGE] FROM [dbo].Artikel [art] WHERE art.$alias = '{0}' -- Inventory of suppliers, external goods UNION SELECT 20000+k.id [KONTO], adr.Match [BEZEICHNUNG], $sqlSupplier [MENGE] FROM [dbo].Kreditor [k] JOIN [dbo].Adresse [adr] ON adr.id = k.AdresseID JOIN [dbo].KrArtikel [kart] ON kart.ArtikelId = (SELECT TOP 1 Id FROM [dbo].Artikel WHERE $alias = '{0}') AND kart.KreditorID = k.id JOIN [dbo].Artikel [art] ON art.id = kart.ArtikelID ) [INVENTORYREPORT] ORDER BY KONTO "@ } <# # This model 'flat' is experimental and not yet fully parameterized [string]$sqlMaster = @" SELECT GTIN [ID.ALIAS] FROM (SELECT ArtNummer [ArticleNo], Barcode [GTIN] FROM Artikel) [Master] WHERE GTIN>='1000000' AND GTIN <='8888889' @" [string]$sqlDetail = @" DECLARE @Id INT DECLARE @IdList TABLE (Id INT) INSERT INTO @IdList SELECT Id FROM Artikel order by id -- VALUES (31), (32), (33) DECLARE @Result TABLE ([Uid] VARCHAR(36), ArticleId INT, ArticleNo VARCHAR(80), GTIN VARCHAR(80), ChangeDate DateTime, ExportFlag Bit, ExportDate DateTime, StockGroup INT, Warehouse VARCHAR(50), Quantity INT) DECLARE IdCursor CURSOR FOR SELECT Id FROM @IdList OPEN IdCursor FETCH NEXT FROM IdCursor INTO @Id WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO @Result -- Inventory from own warehouses SELECT CONVERT(varchar(36), art.Uid) [Uid], art.Id [ArticleId], art.ArtNummer [ArticleNo], IsNull(Art.Barcode,'') [GTIN], art.ChangeDate [ChangeDate], art.ShopFreigabeFlg [ExportFlag], art.ShopExportDatum [ExportDate], lo.id [StockGroup], UPPER(lo.Bezeichnung) [Warehouse], lk.Menge [Quantity] FROM Lagerort lo JOIN dbo.LagerKonto lk on lk.Lagerort = lo.id JOIN Artikel [art] ON art.id = @Id AND art.ArtNummer not like '.MUSTER%' WHERE lo.id >= 1000 AND lo.id < 1400 AND lk.ArtikelId = @Id AND lk.IdentId IS NULL AND lk.PlatzId IS NULL -- Total inventory from all own warehouses that is physically present UNION SELECT CONVERT(varchar(36), art.Uid) [Uid], art.Id [ArticleId], art.ArtNummer [ArticleNo], IsNull(Art.Barcode,'') [GTIN], art.ChangeDate [ChangeDate], art.ShopFreigabeFlg [ExportFlag], art.ShopExportDatum [ExportDate], 10000+1 [StockGroup], 'AVAILABLE' [Warehouse], [dbo].[cnf_BestandVerfuegbarGesamt](@Id,0) [Quantity] FROM Artikel [art] WHERE art.id = @Id AND art.ArtNummer not like '.MUSTER%' -- Total inventory from all own warehouses less sales orders UNION SELECT CONVERT(varchar(36),art.Uid) [Uid], art.Id [ArticleId], art.ArtNummer [ArticleNo], IsNull(Art.Barcode, '') [GTIN], art.ChangeDate [ChangeDate], art.ShopFreigabeFlg [ExportFlag], art.ShopExportDatum [ExportDate], 10000+2 [StockGroup], 'SALES' [Warehouse], [dbo].[cnf_BestandVerfuegbar1](@Id,0) [Quantity] FROM Artikel [art] WHERE art.id = @Id AND art.ArtNummer not like '.MUSTER%' -- Total inventory from all own warehouses less sales orders and plus purchase orders UNION SELECT CONVERT(varchar(36),art.Uid) [Uid], art.Id [ArticleId], art.ArtNummer [ArticleNo], IsNull(Art.Barcode, '') [GTIN], art.ChangeDate [ChangeDate], art.ShopFreigabeFlg [ExportFlag], art.ShopExportDatum [ExportDate], 10000+3 [StockGroup], 'PURCHASE' [Warehouse], [dbo].[cnf_BestandVerfuegbar2](@Id,0) [Quantity] FROM Artikel [art] WHERE art.id = @Id AND art.ArtNummer not like '.MUSTER%' -- Inventory of suppliers, external goods UNION SELECT CONVERT(varchar(36),art.Uid) [Uid], art.Id [ArticleId], art.ArtNummer [ArticleNo], IsNull(Art.Barcode, '') [GTIN], art.ChangeDate [ChangeDate], art.ShopFreigabeFlg [ExportFlag], art.ShopExportDatum [ExportDate], 20000+k.id [StockGroup], adr.Match [Warehouse], IsNull(kart.Bestand,0) [Quantity] FROM Kreditor [k] JOIN Adresse [adr] ON adr.id = k.AdresseID JOIN KrArtikel [kart] ON kart.ArtikelId = @Id AND kart.KreditorID = k.id JOIN Artikel [art] ON art.id = kart.ArtikelID AND art.ArtNummer not like '.MUSTER%' FETCH NEXT FROM IdCursor INTO @Id END CLOSE IdCursor DEALLOCATE IdCursor SELECT GTIN [ARTNUMMER], Quantity [BESTANDVERFUEGBAR], Quantity [BESTANDVERFUEGBAR1], Quantity [BESTANDVERFUEGBAR2] FROM (SELECT [Uid], ArticleId, ArticleNo, GTIN, ChangeDate, ExportFlag, ExportDate, StockGroup, Warehouse, Quantity FROM @Result) [Details] WHERE StockGroup = 1001 AND GTIN>='1000000' AND GTIN <='8888889' AND GTIN = '{0}' "@ #> [string]$sqlLink= 'ID.ALIAS' Write-Debug $sqlMaster Write-Debug $sqlDetail Write-Debug $sqlLink Return [string[]]@($sqlMaster, $sqlDetail, $sqlLink) } function Get-Subnet { [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false)] [int]$cidr , [Parameter(Position=1, Mandatory=$false)] [string]$localIp ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if (! $Cidr) { if (! $localIp) { $localIp= Get-LocalIp } $localIpObj= [IPAddress]::Parse($localIp) $cidr = (Get-NetIPAddress -AddressFamily IPv4 -IPAddress $localIpObj).PrefixLength } $subnet= ([IpAddress]([math]::pow(2, 32) -1 -bxor [math]::pow(2, (32 - $cidr))-1)).IpAddressToString } catch { $subnet= '0.0.0.0' } Return $subnet } function Get-TempDir { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$tempDir = [System.IO.Path]::GetTempPath() if ($tempDir.Substring($tempDir.Length-1) -eq '\') { $tempDir = $tempDir.substring(0, $tempDir.Length - 1) } if ($tempDir -eq "\") { $tempDir = "" } Return $tempDir } function Get-TranslateSection { [CmdletBinding()] param( [Parameter(Position=0, Mandatory = $true)] [string]$text , [Parameter(Position=1, Mandatory = $true)] [ValidateLength(2,2)] [string]$iso , [Parameter(Mandatory = $false)] [string]$sub , [Parameter(Mandatory = $false)] [string]$subDefault ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $iso = $iso.ToUpper() $sub = $sub.ToUpper() $subDefault = $subDefault.ToUpper() [string]$isoTemp = "" [string]$subTemp = "" [string]$isoCurrent = "" [string]$subCurrent = "" [System.Collections.ArrayList]$result = @() $arrLines = $text.Replace("`r`n", "`n").Split("`n") Foreach ($line in $arrLines) { if ((Get-TranslateIsDelim -value $line) -eq $true) { [string[]]$delim = Get-TranslateExtractTag -value $line [string]$isoTemp = $delim[0] [string]$subTemp = $delim[1] If (($isoCurrent -eq $iso) -and ($subCurrent -eq $sub)) { break } if ((! $isoCurrent) -and ($isoTemp -eq $iso) -and ($subTemp -eq $sub)) { [System.Collections.ArrayList]$result = @() $isoCurrent = $isoTemp $subCurrent = $subTemp } } else { # Iso tag language separator found and sort by it if ((($isoCurrent -eq $iso) -and ($subCurrent -eq $sub)) -or ((! $isoCurrent) -and (! $isoTemp) -and (!$sub)) -or ((! $isoCurrent) -and ($isoTemp -eq "00") -and ($subTemp -eq $sub))) { $result.add($line) | Out-Null } } } if (($result.count -eq 0) -and ($sub) -and ($subDefault)) { $result.Add($subDefault) | Out-Null } Return $result -join "`r`n" } function Hide-Extensions { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) Push-Location Set-Location HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced if ((Get-ItemProperty .).HideFileExt -eq 0) { Set-ItemProperty . HideFileExt 1 Start-Sleep -Milliseconds 500 Update-Desktop } Pop-Location } Function Install-SignTool { [CmdletBinding()] param( [string]$signToolBasePath= "$env:TEMP" , [string]$isoBasePath= "$env:TEMP" , [switch]$leaveIso , [switch]$noBuild , [switch]$noInstall ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [hashtable]$headers = @{"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"} [string]$url = "https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/" # ------------------------ # Download Link # ------------------------ $response = Invoke-WebRequest -uri $url -Headers $headers -UseDefaultCredentials -UseBasicParsing -SessionVariable cookieContainer [string]$downloadLink= $null foreach ($link in $response.Links) {if ($link.outerHTML -match "Download the \.iso") {$downloadLink = $link.href; break } } # ------------------------ # Download Iso # ------------------------ if ($downloadLink) { $response = Invoke-WebRequest -uri $downloadLink -Headers $headers -Method Head -UseBasicParsing -SessionVariable cookieContainer [string]$filename = $response.Headers['Content-Disposition'].Split('; ')[1].Split('=')[1] [string]$build= $filename.Split('.')[0] [string]$isoPath= "$isoBasePath\$filename" # Invoke-WebRequest -uri $downloadLink -Headers $headers -UseBasicParsing -SessionVariable cookieContainer -OutFile "$isoPath" Write-Host -NoNewline "Downloading Windows SDK (ca. 1.5 GB)..." -ForegroundColor Blue (New-Object System.Net.WebClient).DownloadFile($downloadLink, $isoPath) Write-Host " (ready)" } else { throw "Download link for SDK not found on sdk website!" } # ------------------------ # Extract ISO # ------------------------ Mount-DiskImage -ImagePath $isoPath -StorageType ISO | Out-Null [string]$isoDrive = (Get-Volume -FriendlyName "KSDK*" | Select-Object -ExpandProperty DriveLetter) + ":\" [string]$sourcePath = "$isoDrive\Installers" if ($noBuild) { [string]$signToolPath = "$signToolBasePath\Signtool" } else { [string]$signToolPath = "$signToolBasePath\Signtool($build)" } if (! (Test-Path $signToolPath )) { New-Item -ItemType Directory -Path $signToolPath -force | Out-Null } [string]$installer= "Windows SDK Signing Tools-x86_en-us.msi" if (! (Test-path "$sourcePath\$installer")) { [string]$installer= "Windows SDK Signing Tools-x86_en-us.exe" } # Extracting Items Copy-Item "$sourcePath\$installer" $signToolPath -force Copy-Item "$sourcePath\4c3ef4b2b1dc72149f979f4243d2accf.cab" $signToolPath -force Copy-Item "$sourcePath\685f3d4691f444bc382762d603a99afc.cab" $signToolPath -force Copy-Item "$sourcePath\e5c4b31ff9997ac5603f4f28cd7df602.cab" $signToolPath -force Copy-Item "$sourcePath\e98fa5eb5fee6ce17a7a69d585870b7c.cab" $signToolPath -force Dismount-DiskImage -ImagePath $isoPath | Out-Null if (! $leaveIso) { Remove-Item $isoPath -Force } # ------------------------ # Install SignTool # ------------------------ if (! $noInstall) { $msiPath = "$signToolPath\$installer" $arguments = "/i `"$msiPath`" /qn" Start-Process msiexec.exe -ArgumentList $arguments -Wait -Verb RunAs Remove-Item -Path "$signToolPath\*.cab" -Force Remove-Item -Path "$signToolPath\$installer" -Force Remove-Item -Path "$signToolPath" -Force } } function New-Delivery { [CmdletBinding()] param ( [parameter(Mandatory=$true)] [ValidateRange(1, [int]::MaxValue)] [int]$salesOrderId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [long]$adUseClient = 3 [long]$adOpenKeyset = 1 [long]$adLockOptimistic = 3 [long]$adCmdText = 1 [long]$adStateOpen = 1 $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { [int]$deliveryId = 0 $sql = "SET NOCOUNT ON`r`n" +` "DECLARE @Af_Id int`r`n" +` "DECLARE @Lf_Id int`r`n" +` "SET @Af_Id = $salesOrderId`r`n" +` "EXEC dbo.cn_TraAfLf_SingleAf @Lf_Id=@Lf_Id OUT, @af_id=@Af_Id`r`n" +` "SELECT @Lf_Id [Id]" $rs = new-object -comObject ADODB.Recordset $rs.CursorLocation = $adUseClient $rs.Open($sql, $myConn, $adOpenKeyset, $adLockOptimistic, $adCmdText) if ($rs) { # Toggle all record sets until you find an open one Do { If ($rs.State -ne $adStateOpen) { $rs = $rs.NextRecordset() } } until ( (! $rs) -or ($rs.State -eq $adStateOpen) ) # Get the id of the new order if (! $rs.eof) { [int]$deliveryId = $rs.fields('Id').value } } else { throw "The '$($myInvocation.MyCommand)' function has failed. Record set is closed. Sql: $sql" } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $deliveryId } function New-DeliveryPropertyItem { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$propertyId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { if ($deliveryId) { [string]$sqlFrag = "Id = $deliveryId" } elseif ($deliveryNo) { [string]$sqlFrag = "KopfNummer = $deliveryNo" } else { throw "The delivery note cannot be loaded, either parameter DeliveryId or DeliveryNo must be specified. Function: $($myInvocation.MyCommand)" } [string]$sql = @" DECLARE @KopfId INT; DECLARE @ObjektId INT; SELECT TOP 1 @ObjektId = ID FROM Lieferschein WHERE $sqlFrag; SET @KopfId = $propertyId; INSERT INTO MerkmalElement (KopfId, ObjektId) SELECT @KopfId, @ObjektId WHERE NOT EXISTS (SELECT 1 FROM MerkmalElement WHERE KopfId = @KopfId AND ObjektId = @ObjektId); "@ $myConn.Execute($sql) | out-null } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } class EulException : Exception { [string] $additionalData EulException($message, $additionalData) : base($message) { $this.additionalData = $additionalData } } function New-EulException { [CmdletBinding()] param( $message, $additionalData ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) return [EulException]::New($message,$additionalData) } Class EulLog : System.IDisposable { [string]$filePath [string]$name EulLog($name, $path) { $this.Name = $name $this.FilePath = $this.ChkPath($path) $this.Put('Initialization') } [void]Dispose() { $this.Put('Finalization') } [string]Fname($name) { $monthYear = Get-Date -Uformat "%Y-%b" return "LOG_$name`_$monthYear.txt" } [string]ChkPath($path) { $fName = $this.Fname($this.name) if (!(Get-Content "$path\events\$fName")) { [void](New-Item -Path "$path\events\$fName" -ItemType File -Force) } return "$path\events\$fName" } # main entry for logging an event [void]Put($level, $group, $message) { $now = (Get-Date).tostring("yyyy-MM-dd HH:mm:ss") if (! (test-path variable:global:processId)) { $global:processId = "$([System.Guid]::NewGuid())" } $delim = "`t" $log= "{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}{6}" -f $delim, $now, ($this.name), $global:processId, $level, $group, $message Write-Debug $log [int]$maxRetries = 30 [int]$i = 0 while ($i -lt $maxRetries) { try { $log | Out-File -FilePath $this.filePath -Append -NoClobber $i = $maxRetries } catch { $i++ Write-Host "$_ Logfile: $log retries: $i from $maxRetries" -ForegroundColor Red Start-Sleep -Seconds 0.1 } } } # short way to log an event [void]Put($level, $message) { $this.Put($level,'(default)',$message) } # shortest way to log an event [void]Put($message) { $this.Put(0,'(default)',$message) } } function New-EulLog { [CmdletBinding()] param ( $name, $path ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) return [EulLog]::New($name, $path) } function New-SalesOrder { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$invoiceAddressId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [long]$adUseClient = 3 [long]$adOpenKeyset = 1 [long]$adLockOptimistic = 3 [long]$adCmdText = 1 [long]$adStateOpen = 1 $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [int]$result = 0 try { $rs = $Null # Create an empty sales order head [string]$sql = "SET NOCOUNT ON`r`n" +` "DECLARE @Af_Id int`r`n" +` "DECLARE @Ad_Id int`r`n" +` "SET @Ad_Id = $invoiceAddressId`r`n" +` "EXEC dbo.cn_CreAf @Af_Id = @Af_Id out, @Ad_Id = @Ad_Id`r`n" +` "SELECT @Af_Id [Id]" $rs = new-object -comObject ADODB.Recordset $rs.CursorLocation = $adUseClient $rs.Open($sql, $myConn, $adOpenKeyset, $adLockOptimistic, $adCmdText) # Toggle all record sets until you find an open one Do { If ($rs.State -ne $adStateOpen) { $rs = $rs.NextRecordset() } } until ( (! $rs) -or ($rs.State -eq $adStateOpen) ) # Get the id of the new order if (! $rs.eof) { [int]$result = $rs.fields('Id').value } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function New-Shortcut { [CmdletBinding()] param( [string]$file , [string]$link ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { if (! (Test-Path $link)) { if (Test-Path $file) { $wshShell = New-Object -comObject WScript.Shell $shortcut = $wshShell.CreateShortcut($Link) $shortcut.TargetPath = $file $shortcut.Save() } else { Write-Host "WARNING! File '$file' is missing, no shortcut is created! Function: $($myInvocation.MyCommand)" -foregroundcolor Magenta } } } catch { Write-Host "ERROR! $_. Function: $($myInvocation.MyCommand)" -foregroundcolor "red" } } function New-Table { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$tableName , [Parameter(Mandatory=$true)] $columnNames ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($columnNames.GetType().Name -eq "String") { $columnNames = $columnNames -split "," } elseif ($columnNames.GetType().BaseType.Name -ne "Array") { throw 'The name of the collumn must be string!' } $tempTable = New-Object System.Data.DataTable $count = 0 if ($columnNames.count -ne 0) { do { Remove-Variable -Name datatype -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $tempTable.Columns.Add() | Out-Null if ($columnNames[$count] -like "*/?*") { $datatype = $columnNames[$count].Substring($columnNames[$count].IndexOf("/?")+2) $columnNames[$count] = $columnNames[$count].Substring(0,$columnNames[$count].IndexOf("/?")) if ($datatype -notlike "System.*") { $datatype = "System."+$datatype } $tempTable.Columns[$count].DataType = $datatype } $tempTable.Columns[$count].ColumnName = $columnNames[$count] $tempTable.Columns[$count].Caption = $columnNames[$count] $count++ } until ($count -eq $columnNames.Count) } Set-Variable -Name $tableName -Scope Global -Value (New-Object System.Data.DataTable) Set-Variable -Name $tableName -Scope Global -Value $tempTable Remove-Variable -Name TempTable -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } function New-TempDir { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $parent = [System.IO.Path]::GetTempPath() [string]$name = [System.Guid]::NewGuid() [string]$path = (Join-Path $parent $name) New-Item -ItemType Directory -Path $path | Out-Null Return $path } function Out-Beep { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [console]::beep(500,300) } function Out-Goodbye { [CmdletBinding()] Param ( [switch]$normally , [switch]$abnormally ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if (! (test-path variable:global:startTime)) { $global:startTime = Get-Date } $global:endTime = Get-Date write-host "Execution start: $(Use-Culture -culture 'en-US' -script {$($global:startTime)})" -ForegroundColor "blue" write-host "Execution end: $(Use-Culture -culture 'en-US' -script {$($global:endTime)})" -ForegroundColor "blue" $ts = New-Timespan -end $global:endtime -start $global:startTime Write-Host "Duration: $(($ts.TotalSeconds).ToString('0.##')) seconds" -ForegroundColor "blue" if ($normally) { Write-Host "Job finished normally" -ForegroundColor "blue" } if ($abnormally) { Write-Host "Job finished abnormally" -ForegroundColor "red" } } function Out-Welcome { [CmdletBinding()] Param ( [parameter(Position = 0, Mandatory=$false)] [ValidateScript({ if(-Not ($_ | Test-Path) ) { throw "File or folder '$_' does not exist!" } else { $true } })] [ValidateScript({ if($_ -notmatch "(\.ps1)") { throw "The file '$_' specified in the path argument must of type .ps1" } else { $true } })] [string]$projectScript , [parameter(Position = 1, Mandatory=$false)] [switch]$noBanner , [parameter(Position = 2, Mandatory=$false)] [switch]$noInfo , [parameter(Position = 3, Mandatory=$false)] [string]$culture ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$OUT_WELCOME_VERSION = 'OUT_WELCOME_VERSION' # EulandaConnect: {0} v{1} [string]$OUT_WELCOME_LICENSEURI = 'OUT_WELCOME_LICENSEURI' # {0} [string]$OUT_WELCOME_COPYRIGHT = 'OUT_WELCOME_COPYRIGHT' # Copyright: {0} [string]$OUT_WELCOME_PROJECTVERSION = 'OUT_WELCOME_PROJECTVERSION' # CustomProject: {0} v{1} [string]$OUT_WELCOME_STARTTIME = 'OUT_WELCOME_STARTTIME' # Execution start: {0} [string]$OUT_WELCOME_PATH = 'OUT_WELCOME_PATH' # Module Path: {0} $global:startTime = Get-Date $banner = @" ________ ____ ___ _ ______ ___ / ____/ / / / / / | / | / / __ \/ | / __/ / / / / / / /| | / |/ / / / / /| | / /___/ /_/ / /___/ ___ |/ /| / /_/ / ___ | /_____/\____/_____/_/ |_/_/ |_/_____/_/ |_| _____ ______ / ___/____ / __/ /__ ______ _________ \__ \/ __ \/ /_/ __/ | /| / / __ / ___/ _ \ ___/ / /_/ / __/ /_ | |/ |/ / /_/ / / / __/ /____/\____/_/ \__/ |__/|__/\__,_/_/ \___/ "@ if (! $noBanner) { write-host $banner -ForegroundColor "blue" } $moduleName = 'EulandaConnect' $module = Get-Module -Name $moduleName if (! $culture) { $culture = [System.Threading.Thread]::CurrentThread.CurrentCulture.Name } else { $cultureObj = [System.Globalization.CultureInfo]::GetCultureInfo($culture) [System.Threading.Thread]::CurrentThread.CurrentCulture = $cultureObj [System.Threading.Thread]::CurrentThread.CurrentUiCulture = $cultureObj # Set-Culture -CultureInfo $culture $global:userlang = $culture } [version]$global:eulandaConnectVersion = $module.Version [string]$copyright = $module.Copyright [string]$licenseURI = $module.LicenseUri if ($projectScript) { [string]$global:scriptDir= Split-Path -Parent $projectScript Set-Location $global:scriptDir $global:projectName= Split-Path -LeafBase $projectScript [version]$global:projectVersion= Read-VersionFromSynopsis -path $projectScript } else { [string]$global:scriptDir= "" [string]$global:projectName= "" [version]$global:projectVersion = "0.0" } Write-Debug (get-module -Name EulandaConnect).path if (! $noInfo) { if ($global:eulandaConnectVersion) { Write-Host ( (Get-ResStr($OUT_WELCOME_VERSION) ) -f $moduleName, $($global:eulandaConnectVersion.ToString())) -ForegroundColor Blue } if ($copyright) { Write-Host ( (Get-ResStr($OUT_WELCOME_COPYRIGHT) ) -f $($copyright)) -ForegroundColor Blue } if ($licenseURI) { Write-Host ( (Get-ResStr($OUT_WELCOME_LICENSEURI) ) -f $($licenseURI)) -ForegroundColor Blue } Write-Host ( (Get-ResStr($OUT_WELCOME_PATH) ) -f $($module.path)) -ForegroundColor Blue write-host ( (Get-ResStr($OUT_WELCOME_STARTTIME) ) -f $(Use-Culture -culture $culture -script {$($global:startTime.toString())})) -ForegroundColor Blue if ($global:projectVersion -gt [version]"0.0") { write-host ( (Get-ResStr($OUT_WELCOME_PROJECTVERSION) ) -f $($global:projectName), $($global:projectVersion.ToString())) -ForegroundColor Green } } } function Protect-String { [CmdletBinding()] param( [Parameter(Position=0, Mandatory = $true)] [string]$plainText, [Parameter(Position=1, Mandatory = $true)] $key ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $key = Get-ProtectedKey $key $securestring = New-Object System.Security.SecureString $chars = $plainText.toCharArray() foreach ($char in $chars) { $secureString.AppendChar($char) } $protectedText = ConvertFrom-SecureString -SecureString $secureString -Key $key return $protectedText } function Read-IniFile { [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] [ValidateScript({ if(-Not ($_ | Test-Path) ){ throw "File or folder does not exist" } if(-Not ($_ | Test-Path -PathType Leaf) ){ throw "The path argument must be a file. Folder paths are not allowed." } if($_ -notmatch "(\.ini)"){ throw "The file specified in the path argument must be either of type ini" } return $true })] [System.IO.FileInfo]$path ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if (!(test-path variable:section)) {[string]$section = $null} [int]$commentCount = 0 if (test-path $path) { $ini = @{} $data = get-content $path -Encoding Default switch -regex($data) { "^\[(.+)\]" # Section { $section = $matches[1] if (!$ini[$section]) { $ini[$section] = [ordered]@{} } $commentCount = 0 } "^(;.*)$" # Comment { if (!($section)) { $section = "No-Section" if (! $ini[$section]) { $ini[$section] = @{} } } [string]$value = $matches[1] $commentCount = $commentCount + 1 $name = "Comment" + $commentCount } "(.+?)\s*=(.*)" # Key { if (!($section)) { $section = "No-Section" if (!$ini[$section]) { $ini[$section] = [ordered]@{} } } $name,$value = $matches[1..2] if ($ini[$section].Contains($name)) { $ini[$section][$name] = $value.Trim() } else { $ini[$section].Add($name, $value.Trim()) } } } } return $ini } function Read-VersionFromSynopsis { [CmdletBinding()] param( [parameter(Position = 0, Mandatory=$true)] [ValidateScript({ if(-Not ($_ | Test-Path) ) { throw "File or folder '$_' does not exist!" } else { $true } })] [ValidateScript({ if($_ -notmatch "(\.ps1)") { throw "The file '$_' specified in the path argument must of type .ps1" } else { $true } })] [string]$path , [parameter(Position = 1, Mandatory=$false)] [ValidateRange(2, [int]::MaxValue)] [int]$maxLines = 250 ) [version]$ProjectVersion = "0.0" try { $content = Get-Content -Path $path -TotalCount $maxLines | Out-String $startIndex = $content.IndexOf(".NOTES") $endIndex = $content.IndexOf("#>") + 2 if ($endIndex -gt $startIndex) { $synopsis = $content.Substring($startIndex, $endIndex - $startIndex) $arrSynopsis = $synopsis.Split("`n") foreach ($line in $arrSynopsis) { if ($line.ToLower().Contains('version:')) { [version]$ProjectVersion = $line.Substring($line.IndexOf(":") + 1).Trim() break } } } } catch { } Return $ProjectVersion } function Receive-SftpFile { [CmdletBinding()] Param( [parameter(Mandatory=$true)] [string]$server , [parameter(Mandatory=$false)] [int]$port= 22 , [parameter(Mandatory=$false)] [string]$user , [parameter(Mandatory=$false)] [string]$password , [parameter(Mandatory=$false)] [string]$remoteFolder , [parameter(Mandatory=$false)] [string]$file , [parameter(Mandatory=$false)] [string]$localFolder , [parameter(Mandatory=$false)] [string]$comObject= 'IPWorksSSH.SFTP' , [parameter(Mandatory=$false)] [string]$license= '(you have to buy one license from n/software)' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $sftp = New-SftpInstance -comObject $comObject $sftp.ok = $license $sftp.Config("SSHAcceptAnyServerHostKey=true") $sftp.Overwrite = $true $sftp.SSHHost = $server $sftp.SSHPassword = $password $sftp.SSHAuthMode = 2 $sftp.SSHUser = $user $sftp.SSHPort = $port $sftp.SSHLogon($sftp.SSHHost, $sftp.SSHPort) $sftp.LocalFile = "$localFolder\$file" $sftp.RemoteFile = "$remoteFolder/$file" $sftp.Download() $sftp.SSHLogoff() } function Remove-DeliveryPropertyItem { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$propertyId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { if ($deliveryId) { [string]$sqlFrag = "Id = $deliveryId" } elseif ($deliveryNo) { [string]$sqlFrag = "KopfNummer = $deliveryNo" } else { throw "Property cannot be removed, either DeliveryId or DeliveryNo parameter must be specified. Function $($myInvocation.MyCommand)" } [string]$sql = @" DECLARE @KopfId INT; DECLARE @ObjektId INT; SELECT TOP 1 @ObjektId = ID FROM Lieferschein WHERE $sqlFrag; SET @KopfId = $propertyId; DELETE MerkmalElement WHERE KopfId = @KopfId AND ObjektId = @ObjektId; "@ $myConn.Execute($sql) | out-null } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } function Remove-ItemWithRetry { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$path ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $stoploop = $false [int]$retrycount = "0" do { try { if (Test-Path $path) { if ($path.ToUpper().IndexOf('\TEMP\')) { Remove-Item -Path $path -Recurse -Force } else { Remove-Item -Path $path -Force } } $stopLoop = $true } catch { if ($retryCount -gt 5) { Write-Host "ERROR In $($myInvocation.MyCommand) Not possible to delete file $path! $_" -foregroundcolor "red" $stopLoop = $true $Error.Clear() } else { $Error.Clear() Write-Host "HINT! Removing file '$path' not working. Retry count '$retryCount'. Trying again..." -foregroundcolor "green" Start-Sleep -Seconds 10 $retryCount = $retryCount + 1 } } } While ($stopLoop -eq $false) } function Remove-SftpFile { [CmdletBinding()] Param( [parameter(Mandatory=$true)] [string]$server , [parameter(Mandatory=$false)] [int]$port= 22 , [parameter(Mandatory=$false)] [string]$user , [parameter(Mandatory=$false)] [string]$password , [parameter(Mandatory=$false)] [string]$remoteFolder , [parameter(Mandatory=$true)] [string]$file , [parameter(Mandatory=$false)] [string]$comObject= 'IPWorksSSH.SFTP' , [parameter(Mandatory=$false)] [string]$license= '(you have to buy one license from n/software)' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $sftp = New-SftpInstance -comObject $comObject $sftp.ok = $license $sftp.Config("SSHAcceptAnyServerHostKey=true") $sftp.Overwrite = $true $sftp.SSHHost = $server $sftp.SSHPassword = $password $sftp.SSHAuthMode = 2 $sftp.SSHUser = $user $sftp.SSHPort = $port $sftp.SSHLogon($sftp.SSHHost, $sftp.SSHPort) $sftp.DeleteFile("$remoteFolder/$file") $sftp.SSHLogoff() } function Rename-MssqlDatabase { [CmdletBinding()] param( [parameter(Mandatory=$true)] [string]$oldName , [parameter(Mandatory=$true)] [string]$newName , [parameter(Mandatory=$false)] [string]$server , [parameter(Mandatory=$false)] [string]$user , [parameter(Mandatory=$false)] [string]$password , [parameter(Mandatory=$false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $connParams = @{ server = $server database = 'Master' user = $user password = $password conn = $conn udl = $udl connStr = $connStr } # Initialize connection and command objects $myConn= Get-Conn -conn $conn -udl $udl -connStr (Get-ConnStr @connParams) try { [string]$sql = "SELECT DB_ID('$oldName') [DbId]" $rs = Get-AdoRs -recordset $myConn.Execute($sql) if ($rs) { [int]$dbId= $rs.fields('DbId').value if (! $dbId) { throw "No DB_ID found!" } } else { throw "No valid recordset found! Function: $myInvocation.Mycommand" } # Get path the logical file names [string]$sql = "SELECT name FROM sys.sysaltfiles WHERE dbid = $dbId and filename like N'%.mdf'" $rs = Get-AdoRs -recordset $myConn.Execute($sql) if ($rs) { [string]$oldLogicalMdf= $rs.fields('name').value if (! $oldLogicalMdf) { throw "No path for oldLogicalMdf found! Function: $myInvocation.Mycommand" } } else { throw "No valid recordset found! Function: $myInvocation.Mycommand" } [string]$sql = "SELECT name FROM sys.sysaltfiles WHERE dbid = $dbId and filename like N'%.ldf'" $rs = Get-AdoRs -recordset $myConn.Execute($sql) if ($rs) { [string]$oldLogicalLdf= $rs.fields('name').value if (! $oldLogicalLdf) { throw "No path for oldLogicalLdf found! Function: $myInvocation.Mycommand" } } else { throw "No valid recordset found! Function: $myInvocation.Mycommand" } # Get path the physical file names [string]$sql = "SELECT filename FROM sys.sysaltfiles WHERE dbid = $dbId and filename like N'%.mdf'" $rs = Get-AdoRs -recordset $myConn.Execute($sql) if ($rs) { [string]$oldPhysicalMdf= $rs.fields('filename').value if (! $oldPhysicalMdf) { throw "No path for oldPhysicalMdf found! Function: $myInvocation.Mycommand" } } else { throw "No valid recordset found! Function: $myInvocation.Mycommand" } [string]$sql = "SELECT filename FROM sys.sysaltfiles WHERE dbid = $dbId and filename like N'%.ldf'" $rs = Get-AdoRs -recordset $myConn.Execute($sql) if ($rs) { [string]$oldPhysicalLdf= $rs.fields('filename').value if (! $oldPhysicalLdf) { throw "No path for oldPhysicalLdf found! Function: $myInvocation.Mycommand" } } else { throw "No valid recordset found! Function: $myInvocation.Mycommand" } # Get the path from the data folder and the names from the MDF and LDF file [string]$path = Split-Path $oldPhysicalMdf $oldPhysicalMdf = Split-Path $oldPhysicalMdf -Leaf $oldPhysicalLdf = Split-Path $oldPhysicalLdf -Leaf # Rename the database, to do this log out all logged in users by putting # the database into single user mode [string]$sql = ` "ALTER DATABASE [$oldName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", ` "ALTER DATABASE [$oldName] MODIFY NAME = [$newName]", ` "ALTER DATABASE [$newName] SET MULTI_USER" $myConn.Execute($sql) | Out-Null # Build the new logical filenames [string]$newLogicalMdf = $newName [string]$newLogicalLdf = $newName + "_Log" # Build the new physical filenames [string]$newPhysicalMdf = $newName + ".mdf" [string]$newPhysicalLdf = $newName + "_log.ldf" # Rename the logical file names, this is only possible under their new name, # then take them offline to rename the files in the file system as well [string]$sql = ` "ALTER DATABASE [$newName] MODIFY FILE (NAME = [$oldLogicalMdf], NEWNAME = [$newLogicalMdf])", ` "ALTER DATABASE [$newName] MODIFY FILE (NAME = [$oldLogicalLdf], NEWNAME = [$newLogicalLdf])", ` "ALTER DATABASE [$newName] SET offline" $myConn.Execute($sql) | Out-Null # Prepare sql server for xp_cmdshell [string]$sql = ` "EXEC sp_configure 'show advanced options', 1", ` "RECONFIGURE", ` "EXEC sp_configure 'xp_cmdshell', 1", ` "RECONFIGURE" $myConn.Execute($sql) | Out-Null # Calls to the sql command shell to rename the file to the new file [string]$sql = ` "EXEC master..xp_cmdshell 'RENAME ""$path\$oldPhysicalMdf"" ""$newPhysicalMdf""'", ` "EXEC master..xp_cmdshell 'RENAME ""$path\$oldPhysicalLdf"" ""$newPhysicalLdf""'" $myConn.Execute($sql) | Out-Null # Makes the new physical files for the database known and puts the DB back online [string]$sql = ` "ALTER DATABASE [$newName] MODIFY FILE (NAME = [$newLogicalMdf], FILENAME = '$path\$newPhysicalMdf')", ` "ALTER DATABASE [$newName] MODIFY FILE (NAME = [$newLogicalLdf], FILENAME = '$path\$newPhysicalLdf')", ` "ALTER DATABASE [$newName] SET online" $myConn.Execute($sql) | Out-Null } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } function Resize-Image { [CmdletBinding()] param( [Parameter(ValueFromPipeline=$true, Position=0, Mandatory=$true)] [ValidateScript({ if (Test-Path $_) { $true } else { throw "Der Pfad '$_' existiert nicht." } })] [string]$pathIn , [Parameter(Position=1, Mandatory=$false)] [string]$pathOut , [Parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] [string]$modifier = "-resized" , [Parameter(Mandatory=$false)] [ValidateRange(10, 100)] [int]$quality = 65 , [Parameter(Mandatory=$false)] [ValidateRange(32, 5000)] [int]$maxWidth = 1200 , [Parameter(Mandatory=$false)] [ValidateRange(32, 5000)] [int]$maxHeight = 1200 , [Parameter(Mandatory=$false)] [switch]$passthru ) Begin { Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { $useDefaultOutputPath = $pathOut -eq '' $pathOutOrg = $pathOut [string]$module= "WIA.ImageFile" $img = New-Object -COMObject $module $imgNew = New-Object -COMObject $module [string]$module= "WIA.ImageProcess" $imgProcess = New-Object -COMObject $module $wiaFormatJpg = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}" $results = @() } catch { throw "The Windows library '$module' is not available. You can install it in the Windows Setup." } } Process { if ($useDefaultOutputPath) { $directoryIn = Split-Path $pathIn $filenameIn = [System.IO.Path]::GetFileNameWithoutExtension($pathIn) $extensionIn = [System.IO.Path]::GetExtension($pathIn) $pathOut = Join-Path $directoryIn ($filenameIn + '$modifier' + $extensionIn) } else { $pathOut = $pathOutOrg $directoryOut = Split-Path $pathOut $filenameOut = [System.IO.Path]::GetFileNameWithoutExtension($pathOut) $extensionOut = [System.IO.Path]::GetExtension($pathOut) $directoryIn = Split-Path $pathIn $filenameIn = [System.IO.Path]::GetFileNameWithoutExtension($pathIn) $extensionIn = [System.IO.Path]::GetExtension($pathIn) write-verbose "***** OUTPUT *****" write-verbose "DirectoryOut $directoryOut" write-verbose "FilenameOut $filenameOut" write-verbose "ExtensionOut $extensionOut" write-verbose "***** INPUT *****" write-verbose "DirectoryIn $directoryIn" write-verbose "FilenameIn $filenameIn" write-verbose "ExtensionIn $extensionIn" if ($directoryOut -eq $directoryIn) { $filenameOut = $filenameIn + '$modifier' } elseif (($filenameOut -eq $filenameIn) -and ($extensionOut -eq $extensionIn)) { $filenameOut = $filenameIn + '$modifier' } elseif (! $extensionOut) { $filenameOut = $filenameIn $extensionOut = $extensionIn $directoryOut = $pathOut } $pathOut = Join-Path $directoryOut ($filenameOut + $extensionOut) } write-verbose "***** USED *****" write-verbose "PFADIN $pathIn" write-verbose "PFADOUT $pathOut" $img.LoadFile($pathIn) $imgProcess.Filters.Add($imgProcess.FilterInfos("Scale").FilterID) $imgProcess.Filters(1).Properties("MaximumWidth") = $maxWidth $imgProcess.Filters(1).Properties("MaximumHeight") = $maxHeight $imgProcess.Filters.Add($imgProcess.FilterInfos("Convert").FilterID) $imgProcess.Filters(2).Properties("FormatID").Value = $wiaFormatJpg $imgProcess.Filters(2).Properties("Quality").Value = $quality $imgNew = $imgProcess.Apply($img) If (Test-Path $pathOut) { Remove-Item -path $pathOut -force } $imgNew.SaveFile($pathOut) $imgProcess.Filters.Remove(2) # Remove the filter backwards $imgProcess.Filters.Remove(1) $result = [PSCustomObject]@{ PathOut = $pathOut } $results += $result if ($passthru) { # Return $result } } End { [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$imgProcess) [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$img) [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$imgNew) if ($passthru) { Return $results } } } function Send-Mail { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [string]$from , [Parameter(Mandatory = $true)] [string[]]$to , [string[]]$cc , [string[]]$bcc , [string]$replyTo = $from , [Parameter(Mandatory = $true)] [Alias("server")] [string]$smtpServer , [ValidateSet('Normal', 'High', 'Low', IgnoreCase = $true)] [string]$priority= 'Normal' , [ValidateSet('utf8NoBOM', 'ascii','bigendianunicode','bigendianutf32', 'oem', 'unicode', 'utf7', 'utf8', 'utf8BOM', 'utf8NoBOM', 'utf32', IgnoreCase = $true)] [string]$encoding= 'utf8' , [string]$user , [string]$password , [secureString]$secPassword , [psCredential]$credential , [switch]$useSsl , [Alias("useHtml")] [switch]$bodyAsHtml , [int]$port= 25 , [Alias("DNO")] [ValidateSet('None', 'OnSuccess', 'OnFailure', 'Delay', 'Never')] [string[]]$deliveryNotificationOption = 'None' , [Parameter(Mandatory = $true)] [string]$subject , [string]$body , [string[]]$attachment ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) # Allowed values SystemDefault, SSL3, Tls, Tls11, Tls12, Tls13. # Since 2012-2023: Tls, Tls11 and Tls12 are working [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor ` [Net.SecurityProtocolType]::Tls11 -bor ` [Net.SecurityProtocolType]::Tls12 # Get Credential by Dialog : $Credential = Get-Credential # Retruning user is like : $User = $credential.Username # Returning plain pPassword : $Password = $credential.GetNetworkCredential().Password [System.Object]$credential = $null if ( ($user) -and ($password ) ) { $secPassword = ConvertTo-SecureString $password -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential ($user, $secPassword) } $mailParams = @{ From = $from To = $to.Split(',') Subject = $subject Port = $port Priority = $priority Encoding = $encoding SmtpServer = $smtpServer DeliveryNotificationOption = $deliveryNotificationOption } if ($cc) {$mailParams.Add('CC', $cc.split(',')) } if ($bcc) {$mailParams.Add('BCC', $bcc.split(',')) } if ($useSsl) {$mailParams.Add('useSSL', $true) } if ($credential) { $mailParams.Add('Credential', $credential ) } if ($bodyAsHtml) {$mailParams.Add('bodyAsHtml', $true) } if ($body) {$mailParams.Add('Body', $body) } if ($attachment) { $mailParams.Add('Attachments', $attachment) } if (( $PSVersionTable.PsVersion.Major -gt 6 ) -or ` (($PSVersionTable.PsVersion.Major -eq 6) -and ` ($PSVersionTable.PsVersion.Minor -ge 2))) { if ($replyTo) { $mailParams.Add('ReplyTo', $replyTo ) } } try { $oldPref = $WarningPreference $WarningPreference = 'SilentlyContinue' Send-MailMessage @mailParams $WarningPreference = $oldPref [string]$message = "Email was sent with subject '$subject'" if ($attachment) {$message += "and attachment: '$attachment'"} write-verbose $message } catch { write-host "ERROR! Email was not sent to '$to'! Subject '$subject'. $_" -foregroundcolor Red } Start-Sleep -Seconds 1 } function Send-SftpFile { [CmdletBinding()] Param( [parameter(Mandatory=$true)] [string]$server , [parameter(Mandatory=$false)] [int]$port= 22 , [parameter(Mandatory=$false)] [string]$user , [parameter(Mandatory=$false)] [string]$password , [parameter(Mandatory=$false)] [string]$remoteFolder , [parameter(Mandatory=$true)] [string]$file , [parameter(Mandatory=$true)] [string]$localFolder , [parameter(Mandatory=$false)] [string]$comObject= 'IPWorksSSH.SFTP' , [parameter(Mandatory=$false)] [string]$license= '(you have to buy one license from n/software)' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $sftp = New-SftpInstance -comObject $comObject $sftp.ok = $license $sftp.Config("SSHAcceptAnyServerHostKey=true") $sftp.SSHHost = $server $sftp.SSHPassword = $password $sftp.SSHAuthMode = 2 $sftp.SSHUser = $user $sftp.SSHPort = $port $sftp.SSHLogon($sftp.SSHHost, $sftp.SSHPort) $sftp.LocalFile = "$localFolder\$file" $sftp.RemoteFile = "$remoteFolder/$file" $sftp.Upload() $sftp.SSHLogoff() } function Set-DeliveryQty { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateScript({ if($_.Count -lt 1) { throw "The array 'quantities' must contain at least one hashtable element with a pair of 'articleNo' and 'qty'." } $true })] [array]$quantities , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [Parameter(Mandatory = $false)] [string]$bookingInfo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr if ($deliveryId) { [string]$sqlFrag = "@lf_id = $deliveryId," } elseif ($deliveryNo) { [string]$sqlFrag = "@KopfNummer = $deliveryNo," } else { throw "There is neither a variable with valid delivery note ID nor a delivery " +` "note number passed!! Function: $($myInvocation.MyCommand) bookingInfo: $bookingInfo" } $xmlFrag = @( $quantities.foreach({ "<UPDATE><ARTNUMMER>" + [Security.SecurityElement]::Escape($_.articleNo) + "</ARTNUMMER>" + "<MENGE>$($_.qty)</MENGE></UPDATE>"}) ); $xmlFrag = $xmlFrag -join "`r`n" $sql = @" set nocount on; declare @Updates xml = N'$xmlFrag'; declare @exec int; exec @exec = dbo.cn_LfUpdateArFromXml $sqlFrag @Updates = @Updates, @xmlVersion = 1, @AfStornoRest = 1, @AfStornoGrund = '$bookingInfo' if @exec < 0 PRINT 'FEHLER' "@ try { $myConn.Execute($sql) | out-null } finally { if ($global:adCloseOnExit) { $myConn.Close() } } <# if ($exec -lt 0) { throw "The sql function to set the new delivery quantities throw an exception! Sql: $sql" } #> } function Set-StockQty { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateScript({ if($_.Count -lt 1) { throw "The array 'quantities' must contain at least one hashtable element with a pair of 'articleNo' and 'qty'." } $true })] [array]$quantities , [Parameter(Mandatory = $false)] [int]$stockGroup = 1 , [Parameter(Mandatory = $false)] [string]$bookingInfo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr $xmlFrag = @( $quantities.foreach({ "<item><ARTNUMMER>" + [Security.SecurityElement]::Escape($_.articleNo) + "</ARTNUMMER>" + "<MENGE>$($_.qty)</MENGE></item>"}) ); $xmlFrag = $xmlFrag -join "`r`n" $bookingInfo = if ($bookingInfo) {"'" + $bookingInfo.replace("'","''") + "'"} else {'null'}; $sql = @" set nocount on; declare @x xml = N'$xmlFrag'; select error from dbo.cnf_ExtractArMenge(@x,1) where error is not null; declare @Mengen [dbo].[TIdQtyTable], @ll_id int; insert @Mengen (id, quantity) select ArtikelId, Menge from dbo.cnf_ExtractArMenge(@x,0); exec dbo.cn_LL_SetBestandAbsolut @LagerGr = $stockGroup, @Mengen = @Mengen, @Objekt = $bookingInfo, @ll_id = @ll_id OUT; "@ try { $myConn.Execute($sql) | out-null } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } function Set-TrackingNo { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [System.Array]$trackingNo , [Parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryId , [Parameter(Mandatory=$false)] [ValidateScript({ if ($_ -eq $null -or $_ -ge 0) {return $true} else {return $false} })] [int]$deliveryNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { if ($deliveryId) { [string]$sqlFrag = "Id = $deliveryId" } elseif ($deliveryNo) { [string]$sqlFrag = "KopfNummer = $deliveryNo" } else { throw "Neither a delivery note id is specified, nor a delivery note number. Function: $($myInvocation.MyCommand)" } [string]$sql = "SELECT Id, KopfNummer [DeliveryNo], SpedAuftragNr [CarrierNo], TrackingNr [TrackingNo], " +` "AnzahlPakete [Units], VersandDatum [ShippingDate] FROM Lieferschein WHERE $sqlFrag" $rs = $Null $rs = new-object -comObject ADODB.Recordset $rs.CursorLocation = $global:adUseClient $rs.Open($sql, $myConn, $global:adOpenKeyset, $global:adLockOptimistic, $global:adCmdText) if (! $rs.eof) { [string]$carrierNo = $rs.fields('CarrierNo').value # Only if this is the secoond document we have for this delivery note # be need to keep the old trackings also. This is indicated by an existing carrierNo. if ($carrierNo) { [string]$tempStr = $rs.fields('TrackingNo').value [int]$oldUnits = $rs.fields('Units').value } else { [string]$tempStr = "" [int]$oldUnits = 0 } [string]$oldValue = $tempStr $tempStr = $tempStr.Replace("`r","").Trim() [System.Array]$tempArray = [System.Collections.ArrayList]::new() $tempArray = $tempStr.split("`n") $tempArray = $tempArray + $trackingNo $tempArray = $tempArray | Select-Object -Unique $tempArray = $tempArray | Sort-Object -Descending $tempStr = $tempArray -join "`r`n" $tempStr = $tempStr.Trim() $tempArray = $tempStr.Split("`r`n") # Avoid unnecessary change dates in the database if (($oldValue -ne $tempStr) -or ($oldUnits -ne $tempArray.count)) { $rs.fields('TrackingNo').value = $tempStr $rs.fields('Units').value = [int]$tempArray.count $rs.fields('ShippingDate').value = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") $rs.update() } } else { throw "The delivery note does not exist in EULANDA-ERP system! DeliveryNo: $deliveryNo" } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } } function Show-Extensions { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) Push-Location Set-Location HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced if ((Get-ItemProperty .).HideFileExt -eq 1) { Set-ItemProperty . HideFileExt 0 Start-Sleep -Milliseconds 500 Update-Desktop } Pop-Location } function Show-MsgBox { [CmdletBinding()] param( [Parameter(Position = 0, Mandatory = $true)] [string]$prompt , [Parameter(Position = 1, Mandatory = $false)] [ValidateSet(0,1,2,3,4,5)] [int]$btn = $mbYesNo , [Parameter(Position = 2, Mandatory = $false)] [string]$title = 'Info' , [Parameter(Position = 3, Mandatory = $false)] [ValidateSet(0,16,32,48,64)] [int]$icon = $mbInfo , [Parameter(Position = 4, Mandatory = $false)] [ValidateSet(0,256,512,768)] [int]$btnDef = $mbNone ) Add-Type -AssemblyName PresentationFramework | Out-Null [int]$result = [System.Windows.MessageBox]::Show((new-object System.Windows.Window -Property @{TopMost = $True}), $prompt, $title, $btn, $icon, $btnDef) Return $result } function Show-MsgBoxYes { [CmdletBinding()] param( [Parameter(Position = 0, Mandatory = $true)] [string]$prompt ) [int]$Result = Show-MsgBox -prompt $prompt -title 'Info' -icon $mbNone -btnDef $mbNone if ($result -eq $mbrYes) { Return $true } else { Return $false } } function Test-Administrator { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $User = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent()) $User.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) } function Test-ArticlePropertyItem { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [Int]$articleId , [Parameter(Mandatory = $true)] [ValidateRange("Positive")] [int]$propertyId , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr [bool]$result = $false try { [string]$sql = @" SELECT CASE WHEN EXISTS (SELECT me.ObjektId FROM MerkmalElement me JOIN Merkmal m ON m.Id = me.KopfId AND m.id = $propertyId AND m.Tabelle = 'Artikel' AND m.MerkmalTyp = 1 WHERE me.ObjektId = $articleId ) THEN 1 ELSE 0 END [Item] "@ $rs = $Null $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { if ($rs.fields('Item').Value -eq 1) { $result = $true } } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function Test-HasProperty { [CmdletBinding()] param( $inputVar , [string]$propertyName ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [bool]$result = $false if ($propertyName) { if ($inputVar) { if ($null -ne $inputVar -and -not $inputVar.GetType().IsValueType) { $result = ($propertyName -in $inputVar.PSobject.Properties.Name) } } } return $result } function Test-SalesOrder { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$customerOrderNo , [Parameter(Mandatory = $false)] $conn , [Parameter(Mandatory = $false)] [string]$udl , [Parameter(Mandatory = $false)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $myConn = Get-Conn -conn $conn -udl $udl -connStr $connStr try { [string]$Sql = "SELECT Id FROM Auftrag WHERE BestellNummer = '$customerOrderNo'" $rs = $Null [bool]$result = $false $rs = $myConn.Execute($sql) if ($rs) { if (! $rs.eof) { [bool]$result = $true } } } finally { if ($global:adCloseOnExit) { $myConn.Close() } } Return $result } function Test-Verbose { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [bool](Write-Verbose ([String]::Empty) 4>&1) } function Test-XmlSchema { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $xmlFile , [Parameter(Mandatory=$true)] [string] $schemaFile ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string[]]$Script:xmlValidationErrorLog = @() [scriptblock] $validationEventHandler = { $Script:xmlValidationErrorLog += "$($args[1].Exception.Message)`r`n" } $xml = New-Object System.Xml.XmlDocument $schemaReader = New-Object System.Xml.XmlTextReader $schemaFile $schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $validationEventHandler) $xml.Schemas.Add($schema) | Out-Null $xml.Load($XmlFile) $xml.Validate($validationEventHandler) if ($Script:xmlValidationErrorLog) { Write-Warning "$($Script:xmlValidationErrorLog.Count) errors found" Throw "$Script:xmlValidationErrorLog" } else { Write-Verbose "The '$(Get-Filename -path $xmlFile)' file has been successfully validated against the '$(Get-Filename -path $schemaFile)' schema." } } function Unprotect-String { [CmdletBinding()] param( [Parameter(Position=0, Mandatory = $true)] $protectedText, [Parameter(Position=1, Mandatory = $true)] $key ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $key = Get-ProtectedKey $key $protectedText | ConvertTo-SecureString -key $key | ForEach-Object { [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($_)) } } function Update-Desktop { [CmdletBinding()] param() Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { $c= Add-Type -Name WinAPI -PassThru -MemberDefinition @' [DllImport("user32.dll")] public static extern IntPtr GetShellWindow(); [DllImport("user32.dll")] public static extern int SendMessageW(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam); '@ $dsktp=$c::GetShellWindow(); $WM_COMMAND=273; $accel_F5=New-Object UIntPtr(41504); $nullptr=[IntPtr]::Zero; [int](($dsktp -eq $nullptr) -or ($c::SendMessageW($dsktp, $WM_COMMAND, $accel_F5, $nullptr) -ne 0)) | Out-Null } catch { } } Function Use-Culture { [CmdletBinding()] param( [System.Globalization.CultureInfo]$culture = (throw "USAGE: Use-Culture -culture culture -script {ScriptBlock}") , [ScriptBlock]$script= (throw "USAGE: Use-Culture -culture culture -script {ScriptBlock}") ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) $oldCulture = [System.Threading.Thread]::CurrentThread.CurrentCulture trap { [System.Threading.Thread]::CurrentThread.CurrentCulture = $oldCulture } [System.Threading.Thread]::CurrentThread.CurrentCulture = $culture Invoke-Command $script [System.Threading.Thread]::CurrentThread.CurrentCulture = $oldCulture } function Write-XmlMetadata { [CmdletBinding()] param( [Parameter(Mandatory=$true)] $writer , [Parameter(Mandatory=$false)] [ValidateSet('none', 'upper', 'lower','capital')] [string]$strCase = 'upper' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$nodeName = (Convert-StringCase -value ('Metadata') -strCase $strCase) $writer.WriteStartElement($nodeName) try { [string]$path = "$(Get-ModulePath('eulLib'))\..\..\EulandaConnect.ps1" [string]$version = "$((Test-ScriptFileInfo -Path $path).Version)" } catch { [string]$version = '' } [string]$nodeName = (Convert-StringCase -value ('Version') -strCase $strCase) $writer.WriteElementString($nodeName,$version) [string]$nodeName = (Convert-StringCase -value ('Generator') -strCase $strCase) $writer.WriteElementString($nodeName,'EulandaConnect') [string]$nodeName = (Convert-StringCase -value ('Dateformat') -strCase $strCase) $writer.WriteElementString($nodeName,'ISO8601') [string]$nodeName = (Convert-StringCase -value ('Floatformat') -strCase $strCase) $writer.WriteElementString($nodeName,'US') [string]$nodeName = (Convert-StringCase -value ('Countryformat') -strCase $strCase) $writer.WriteElementString($nodeName,'ISO2') [string]$nodeName = (Convert-StringCase -value ('Fieldnames') -strCase $strCase) $writer.WriteElementString($nodeName,'NATIVE') [string]$nodeName = (Convert-StringCase -value ('Date') -strCase $strCase) $writer.WriteElementString($nodeName,(Convert-DateToIso -value $(Get-Date) -noTimeZone )) [string]$nodeName = (Convert-StringCase -value ('PCName') -strCase $strCase) $writer.WriteElementString($nodeName, "$env:COMPUTERNAME".ToUpper()) [string]$nodeName = (Convert-StringCase -value ('UserName') -strCase $strCase) $writer.WriteElementString($nodeName, "$env:USERNAME".ToUpper()) $writer.WriteEndElement() Return $writer } # ----------------------------------------------------------------------------- # Private functions # ----------------------------------------------------------------------------- function Find-SqlBrowser { [CmdletBinding()] param( [string]$ip , [int]$port = 1434 , [int]$timeout = 300 ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { $instances = New-Object System.Collections.ArrayList $toASCII = New-Object System.Text.AsciiEncoding $udpEndpoint = New-Object System.Net.IpEndpoint([system.net.ipaddress]::Any,0) $udpPacket = 0x02,0x00,0x00 $udpClient = New-Object System.Net.Sockets.Udpclient $udpClient.Client.ReceiveTimeout = $timeout $udpClient.Connect($ip,$port) $udpClient.Client.Blocking = $true [void]$udpClient.Send($udpPacket, $udpPacket.length) $bytesRecived = $udpClient.Receive([ref]$udpEndpoint) [string]$result = $toASCII.GetString($bytesRecived) If ($result) { $result = $result.Substring(3,$result.Length-3) $result = $result.Replace(';;',"`t") $list = $result.Split("`t").trim() $list = $list | Where-Object { $_ -ne "" } foreach ($item in $list) { $pairs = $item.Split(';') $tempObj= [PSCustomObject]@{ Ip=$Ip } for ($i = 0; $i -lt $pairs.Length; $i += 2) { $key = $pairs[$i] $value = $pairs[$i+1] Add-Member -InputObject $tempObj -MemberType NoteProperty -Name $key -Value $value } $instances.Add($tempObj) | Out-Null } } } catch { # write-host "$_" } finally { $udpClient.close() } Return $instances } function Get-ConnFromStr { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$connStr ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [long]$adUseClient = 3 [long]$adTimeout = 60*20 $conn = new-object -comObject ADODB.Connection $conn.CursorLocation = $adUseClient $conn.ConnectionString = $connStr $conn.CommandTimeout = $adTimeout $conn.open() Return $conn } function Get-ConnFromUdl { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$udl ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [long]$adUseClient = 3 [long]$adTimeout = 60*20 $conn = new-object -comObject ADODB.Connection $conn.CursorLocation = $adUseClient $conn.ConnectionString = "File Name=$udl" $conn.CommandTimeout = $adTimeout $conn.open() Return $conn } function Get-ProtectedKey { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$key ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) if ($key.length -lt 16) { $key = $key.PadRight(16,' ') } elseif ($key.length -lt 32) { $key = $key.PadRight(32,' ') } else { Throw "The key should contain no more than 32 characters. The best security is 32 characters, otherwise 16 characters!" } $length = $key.length $pad = 32-$length $encoding = New-Object System.Text.ASCIIEncoding $bytes = $encoding.GetBytes($key + "0" * $pad) return $bytes } function Get-PunctuationIdx { [CmdletBinding()] Param( [string]$text ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [int]$idx = -1 [int]$i = Get-PunctuationIdxByChar -text $text -Match '.' if ($i -gt $idx) { $idx = $i } [int]$i = Get-PunctuationIdxByChar -text $text -Match '!' if ($i -gt $idx) { $idx = $i } [int]$i = Get-PunctuationIdxByChar -text $text -Match '?' if ($i -gt $idx) { $idx = $i } if ($idx -eq -1) { # if no punctuation is found, then take space char [int]$i = Get-PunctuationIdxByChar -text $text -Match ' ' if ($i -gt $idx) { $idx = $i } } if ($idx -eq -1 ) { $idx = $text.Length-1 } return $idx } function Get-PunctuationIdxByChar { [CmdletBinding()] Param( [string]$text, [string]$match ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [int]$idx = -1 while (1 -eq 1 ) { [Int]$Idx = $text.lastIndexOf($match) if ($match -ne ' ') { if (($idx -ne -1) -and ($idx -lt $text.length-1)) { if ($text.Substring($idx+1, 1) -eq ' ') { break } else { if ($text.length -gt 1) { $text = $Text.SubString(0, $idx) } else { break } } } else { break } } else { break } } if ($idx -le 0) { return -1 } else { if ($match -eq ' ') { return $idx } else { return $idx+1 } } } function Get-RandomParagraph { param( [int]$MinSentences = 2, [int]$MaxSentences = 4 ) $numSentences = Get-Random -Minimum $MinSentences -Maximum $MaxSentences $sentence = "$(Get-RandomWords)$(Get-RandomPunctuation)" for ($i = 1; $i -le $numSentences; $i++) { $sentence = "$(Get-RandomWords)$(Get-RandomPunctuation)" if (! $sentences) { $sentences = $sentence } else { $sentences += " $sentence" } } return $sentences.TrimEnd() } function Get-RandomPunctuation { $punctuations = @(".", ".", ".", ".", ".", "!", "!", "!", "?", "?") $index = Get-Random -Minimum 0 -Maximum $punctuations.Count return $punctuations[$index] } function Get-RandomWords { param( [int]$MinWords = 5, [int]$MaxWords = 20 ) $loremIpsum = "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do " +` "eiusmod tempor incididunt ut labore et dolore magna aliqua ut enim ad minim " +` "veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " +` "commodo consequat Duis aute irure dolor in reprehenderit in voluptate " +` "velit esse cillum dolore eu fugiat nulla pariatur excepteur sint occaecat " +` "cupidatat non proident sunt in culpa qui officia deserunt mollit anim id est " +` "laborum" $words = $loremIpsum.Split() | Where-Object { $_.Length -gt 1 } $numWords = Get-Random -Minimum $MinWords -Maximum $MaxWords $result = "" for ($i = 1; $i -le $numWords; $i++) { $word = $words[(Get-Random -Minimum 0 -Maximum $words.Count)] if ($i -eq 1) { $word = $word.Substring(0, 1).ToUpper() + $word.Substring(1) } if ((Get-Random -Minimum 0 -Maximum 10) -eq 0) { $word = $word.Substring(0, 1).ToUpper() + $word.Substring(1) } $result += $word + " " } return $result.TrimEnd() } function Get-TranslateExtractTag { [CmdletBinding()] param( [string]$value ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [string]$iso = "" [string]$SubVar = "" [string[]]$result = @("", "") $value = $value.Substring(0, $value.Length-1) # delete last $value = $value.Substring(1, $value.Length-1) # delete first $value = $value.ToUpper() # check for an optional part $p = $value.IndexOf(":") if ($p -eq -1) { $iso = $value.ToUpper() } else { if ($p -eq 0 ) { $subVar = $value.Substring(1, $value.Length-1).ToUpper() $iso = "00" # Default } else { $iso = $value.Substring(0, 2).ToUpper() $subVar = $value.SubString(3, $value.Length-3).ToUpper() } } $result[0] = $iso $result[1] = $subVar Return $result } function Get-TranslateIsDelim { [CmdletBinding()] param( [string]$value ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) [bool]$result = $false # test if the first character is an open bracket if ($value.SubString(0,1) -eq "[") { $value = $value.TrimEnd() # test if the last character is a closed bracket if ($value.Substring($value.Length-1) -eq "]") { $value = $value.Substring(0, $value.Length-1) # delete last $value = $value.Substring(1, $value.Length-1) # delete first # check if there is an optional part $p = $value.IndexOf(":") if ($p -eq -1) { # without optional part the iso tag must be 2 characters long if ($value.Length -eq 2) {$result = $True } else { $result = $False } } else { # valid positions for the colon are the first or the third (after the iso-tag) if (($p -eq 0) -or ($p -eq 2)) { $result = $True } else { $result = $False } } } } Return $result } function New-SftpInstance { [CmdletBinding()] param( [parameter(Mandatory=$false)] [string]$comObject= 'IPWorksSSH.SFTP' ) Write-Verbose -Message ('Starting: {0}' -f $MyInvocation.Mycommand) try { $sftp = New-Object -COMObject $comObject } catch { throw "The SFTP library (ocx) '$comObject' is not registred on this pc. " +` "Register it with 'regsvr32 path\sftp160.ocx'. " +` "ATTENTION: The name of the OCX could be diffrent on your system!" } Return $sftp } # SIG # Begin signature block # MIIpiwYJKoZIhvcNAQcCoIIpfDCCKXgCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCb0fVjdkwsDNXD # c48sAKlHDxb1q8tOPJkvQ7AEF5/LDqCCEngwggVvMIIEV6ADAgECAhBI/JO0YFWU # jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI # DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM # EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy # dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG # EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv # IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s # hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD # J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7 # P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme # me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz # T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q # RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz # mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc # QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T # OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/ # AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID # AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD # VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV # HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE # VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v # ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE # KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI # hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF # OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC # J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ # pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl # d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH # +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYcMIIEBKADAgECAhAz1wio # kUBTGeKlu9M5ua1uMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv # ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5 # NTlaMFcxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLjAs # BgNVBAMTJVNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBFViBSMzYwggGi # MA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC70f4et0JbePWQp64sg/GNIdMw # hoV739PN2RZLrIXFuwHP4owoEXIEdiyBxasSekBKxRDogRQ5G19PB/YwMDB/NSXl # wHM9QAmU6Kj46zkLVdW2DIseJ/jePiLBv+9l7nPuZd0o3bsffZsyf7eZVReqskmo # PBBqOsMhspmoQ9c7gqgZYbU+alpduLyeE9AKnvVbj2k4aOqlH1vKI+4L7bzQHkND # brBTjMJzKkQxbr6PuMYC9ruCBBV5DFIg6JgncWHvL+T4AvszWbX0w1Xn3/YIIq62 # 0QlZ7AGfc4m3Q0/V8tm9VlkJ3bcX9sR0gLqHRqwG29sEDdVOuu6MCTQZlRvmcBME # Jd+PuNeEM4xspgzraLqVT3xE6NRpjSV5wyHxNXf4T7YSVZXQVugYAtXueciGoWnx # G06UE2oHYvDQa5mll1CeHDOhHu5hiwVoHI717iaQg9b+cYWnmvINFD42tRKtd3V6 # zOdGNmqQU8vGlHHeBzoh+dYyZ+CcblSGoGSgg8sCAwEAAaOCAWMwggFfMB8GA1Ud # IwQYMBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBSBMpJBKyjNRsjE # osYqORLsSKk/FDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAT # BgNVHSUEDDAKBggrBgEFBQcDAzAaBgNVHSAEEzARMAYGBFUdIAAwBwYFZ4EMAQMw # SwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdv # UHVibGljQ29kZVNpZ25pbmdSb290UjQ2LmNybDB7BggrBgEFBQcBAQRvMG0wRgYI # KwYBBQUHMAKGOmh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0Nv # ZGVTaWduaW5nUm9vdFI0Ni5wN2MwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNl # Y3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4ICAQBfNqz7+fZyWhS38Asd3tj9lwHS # /QHumS2G6Pa38Dn/1oFKWqdCSgotFZ3mlP3FaUqy10vxFhJM9r6QZmWLLXTUqwj3 # ahEDCHd8vmnhsNufJIkD1t5cpOCy1rTP4zjVuW3MJ9bOZBHoEHJ20/ng6SyJ6UnT # s5eWBgrh9grIQZqRXYHYNneYyoBBl6j4kT9jn6rNVFRLgOr1F2bTlHH9nv1HMePp # GoYd074g0j+xUl+yk72MlQmYco+VAfSYQ6VK+xQmqp02v3Kw/Ny9hA3s7TSoXpUr # OBZjBXXZ9jEuFWvilLIq0nQ1tZiao/74Ky+2F0snbFrmuXZe2obdq2TWauqDGIgb # MYL1iLOUJcAhLwhpAuNMu0wqETDrgXkG4UGVKtQg9guT5Hx2DJ0dJmtfhAH2KpnN # r97H8OQYok6bLyoMZqaSdSa+2UA1E2+upjcaeuitHFFjBypWBmztfhj24+xkc6Zt # CDaLrw+ZrnVrFyvCTWrDUUZBVumPwo3/E3Gb2u2e05+r5UWmEsUUWlJBl6MGAAjF # 5hzqJ4I8O9vmRsTvLQA1E802fZ3lqicIBczOwDYOSxlP0GOabb/FKVMxItt1UHeG # 0PL4au5rBhs+hSMrl8h+eplBDN1Yfw6owxI9OjWb4J0sjBeBVESoeh2YnZZ/WVim # VGX/UUIL+Efrz/jlvzCCBuEwggVJoAMCAQICEGilgQZhq4aQSRu7qELTizkwDQYJ # KoZIhvcNAQELBQAwVzELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGlt # aXRlZDEuMCwGA1UEAxMlU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIEVW # IFIzNjAeFw0yMjAxMjcwMDAwMDBaFw0yNDAxMjcyMzU5NTlaMIGmMRIwEAYDVQQF # EwlIUkIgMTg4NzAxEzARBgsrBgEEAYI3PAIBAxMCREUxHTAbBgNVBA8TFFByaXZh # dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJERTEPMA0GA1UECAwGSGVzc2VuMR4w # HAYDVQQKDBVFVUxBTkRBIFNvZnR3YXJlIEdtYkgxHjAcBgNVBAMMFUVVTEFOREEg # U29mdHdhcmUgR21iSDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMzT # O8Mbj+llr7AC7DuCfXcQUJJsAnYeHudXCXyw/vCpdBJLvd3IMkk0EGtl/owTlq9t # m6tdzPTjh4bUjJQVqmsdfo15EldPOI9fTuaoG4xBDeJwhdFC/tiNfq/JsCWWclca # 50QBBo5JDAZvCJSrw71t7s5LLzs0rHMUnDjKyjAWwd7qC+tTZdwaGAppx6bpL9vd # CzLZDQZGbOkZL1eaPikwkou98XY7DeaF/SzpAuQP6oVfgjoe82fLlgXBhl92KGB8 # M+E96okXJNrNFPY3iYWLRJk5D/r0NUkJR+NY/hxC8wnRqLyc9ANh99ykTSe5OlD9 # kx4DlStypnmQIm9oV+oRKr3cXKH+QvWh23sjdw42pkiHK0MP39RJDs5Jk0NG8FUY # MrMTFiTmsxg9sJsLKWmFy/MzvJycVHnyKe6WTMeVz63ouCK/Ep41BIuajW/ivcCx # LfSYAwzxpGQgEdta2eZrvna9+EzTiuEBoaV4mDGTdg1/P8Hjr/9a6fREl82Rqw3W # CCt6ymOb31fxkUSr6Be26CY3JEHnxbb30PsVmNFCdayKjKbjf39zzTEWQRGSywC7 # +bgQWHu2kFvSH9YSWTxDjZdsdrL2bUvmobCTmaDCxTgjRiaBh+jSzhQ0M1MkQNzf # W/gwP4z6a0FO2YatdXJFVGpV4rOzlHOsulFiyvgNAgMBAAGjggHXMIIB0zAfBgNV # HSMEGDAWgBSBMpJBKyjNRsjEosYqORLsSKk/FDAdBgNVHQ4EFgQUsZ5evsRYcZpr # WcPwOErnS2ZxP7cwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0l # BAwwCgYIKwYBBQUHAwMwEQYJYIZIAYb4QgEBBAQDAgQQMEkGA1UdIARCMEAwNQYM # KwYBBAGyMQECAQYBMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20v # Q1BTMAcGBWeBDAEDMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGln # by5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FFVlIzNi5jcmwwewYIKwYB # BQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1Nl # Y3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBRVZSMzYuY3J0MCMGCCsGAQUFBzABhhdo # dHRwOi8vb2NzcC5zZWN0aWdvLmNvbTA2BgNVHREELzAtoBwGCCsGAQUFBwgDoBAw # DgwMREUtSFJCIDE4ODcwgQ1jbkBldWxhbmRhLmRlMA0GCSqGSIb3DQEBCwUAA4IB # gQBNj78jtsmPrpiGXPRt/DAyJJDd8CHHbH7SQpEC2abBc4ypmnseXbSIQlZdySaJ # BOrDqj75gjB5FOSbir9FsIzPLgP2qjTyxsd3FtRcNcXDK7VIZgxmeJh2ipsXAqsB # nivA9Vut2mu72wQ877VSkoUYIe7JMAUDKG0qwHU4LyMXoNYttto2y7yR6odDYwGC # YxXNlPNx9wNVzJOMhnRalP1fwRC9RwjUoizGAEUg5BNh7dKNkSFRzimHh2iAvgeV # akhbV2+IkekWo7GdEwGLLUSUG8tLwLxOXQ2qsJyOPv0bK/OXiqkgyvqzJ3TRZWiS # KNX5jSiwwUBrA8vNyCh6d8ZCorwimYkDyGtstF0D9UoU9dX66QrfTsK+zxO7/0QF # 1qIc5CTZe6Kcsuxe99p5UbPU665d5BvOwq0lJKg59k+6exo1Cc5awip+d4krfyWl # D1sMkS0eiRSN1UNVs3Hg5gbaEEBx98sQMBF45vv0DFgY/SQVRp9yaFayTyfbb/qk # jc8xghZpMIIWZQIBATBrMFcxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdv # IExpbWl0ZWQxLjAsBgNVBAMTJVNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBD # QSBFViBSMzYCEGilgQZhq4aQSRu7qELTizkwDQYJYIZIAWUDBAIBBQCgfDAQBgor # BgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEE # AYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgehzyIIji/WFd # 05h501zDUtqpe89CVmeJD2uMA0N8mrowDQYJKoZIhvcNAQEBBQAEggIAVP7gcK4r # 3aghzn2JltFrlKrg8GUucbkfSv8DonO06qYfcwNWsX3oGZF3WUBWj8jMa+rBadPg # aEXKNogqMtPOanUnY4Twf5l4juHWbRuW3iB8EKD41kmO9RbT/F8dARjC6TYnfljL # t02rJRHBxEFeQyv6+D6sLLkXX49TNuAimX6LrAoK2/50MdHjIh1UFlFDTg0SwVsG # e7CkuiYVGVytIDUDQduQ97rKsOp+R3yo44Cw6YwN0QpIcHpTADFgcnZUpmHSuJvt # X9dTCMg/Fl8nHh/tub5vCRhPgaq13jLN0mK2kmS+91wDOBzJGOMvf824aoIC/fSX # cc1boMx3srrZHOYciTh/0Dqx5mY47+gpOJFIcehX0FAPireSNl/wxBIY1If7DS0Y # GZtxlwGxkM1F11lglcgynRk+x0QRSULx5chesz47t2r3iZ0AkIn2PAcI8wlV3PCT # YTGxBm6KYuOnf1d37LNCXJTcw+ZAJuCBFrYVMIH6QfY0H/bt2u5mefg8LHnHa0NL # 9sbPfPdERXcvoXLM+wu735oXiEt5qFjaoYjzYD/hm0VPGw43IA+3qtB61SQJq6qJ # h7YLgLJPqaW55D0z4QQQuz7FfTy+OIRGwvkX9BlC//inkWwtHv32H8iEnusfDA5c # 8T8VPJLBja6Mrz8eo7fE8O6eqUsatZYlhxqhghNRMIITTQYKKwYBBAGCNwMDATGC # Ez0wghM5BgkqhkiG9w0BBwKgghMqMIITJgIBAzEPMA0GCWCGSAFlAwQCAgUAMIHw # BgsqhkiG9w0BCRABBKCB4ASB3TCB2gIBAQYKKwYBBAGyMQIBATAxMA0GCWCGSAFl # AwQCAQUABCCok8EQ6BPMIunNrDXSrXsvABF5VXaiYN1eqGkgKLHXhQIVAPhhk84I # wQxzWib+9BKBiUmRb2MPGA8yMDIzMDMxOTA1MTAwOVqgbqRsMGoxCzAJBgNVBAYT # AkdCMRMwEQYDVQQIEwpNYW5jaGVzdGVyMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0 # ZWQxLDAqBgNVBAMMI1NlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgU2lnbmVyICMz # oIIN6jCCBvYwggTeoAMCAQICEQCQOX+a0ko6E/K9kV8IOKlDMA0GCSqGSIb3DQEB # DAUAMH0xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIx # EDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDElMCMG # A1UEAxMcU2VjdGlnbyBSU0EgVGltZSBTdGFtcGluZyBDQTAeFw0yMjA1MTEwMDAw # MDBaFw0zMzA4MTAyMzU5NTlaMGoxCzAJBgNVBAYTAkdCMRMwEQYDVQQIEwpNYW5j # aGVzdGVyMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMMI1NlY3Rp # Z28gUlNBIFRpbWUgU3RhbXBpbmcgU2lnbmVyICMzMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEAkLJxP3nh1LmKF8zDl8KQlHLtWjpvAUN/c1oonyR8oDVA # BvqUrwqhg7YT5EsVBl5qiiA0cXu7Ja0/WwqkHy9sfS5hUdCMWTc+pl3xHl2Attgf # YOPNEmqIH8b+GMuTQ1Z6x84D1gBkKFYisUsZ0vCWyUQfOV2csJbtWkmNfnLkQ2t/ # yaA/bEqt1QBPvQq4g8W9mCwHdgFwRd7D8EJp6v8mzANEHxYo4Wp0tpxF+rY6zpTR # H72MZar9/MM86A2cOGbV/H0em1mMkVpCV1VQFg1LdHLuoCox/CYCNPlkG1n94zrU # 6LhBKXQBPw3gE3crETz7Pc3Q5+GXW1X3KgNt1c1i2s6cHvzqcH3mfUtozlopYdOg # XCWzpSdoo1j99S1ryl9kx2soDNqseEHeku8Pxeyr3y1vGlRRbDOzjVlg59/oFyKj # eUFiz/x785LaruA8Tw9azG7fH7wir7c4EJo0pwv//h1epPPuFjgrP6x2lEGdZB36 # gP0A4f74OtTDXrtpTXKZ5fEyLVH6Ya1N6iaObfypSJg+8kYNabG3bvQF20EFxhjA # UOT4rf6sY2FHkbxGtUZTbMX04YYnk4Q5bHXgHQx6WYsuy/RkLEJH9FRYhTflx2mn # 0iWLlr/GreC9sTf3H99Ce6rrHOnrPVrd+NKQ1UmaOh2DGld/HAHCzhx9zPuWFcUC # AwEAAaOCAYIwggF+MB8GA1UdIwQYMBaAFBqh+GEZIA/DQXdFKI7RNV8GEgRVMB0G # A1UdDgQWBBQlLmg8a5orJBSpH6LfJjrPFKbx4DAOBgNVHQ8BAf8EBAMCBsAwDAYD # VR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDBKBgNVHSAEQzBBMDUG # DCsGAQQBsjEBAgEDCDAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29t # L0NQUzAIBgZngQwBBAIwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC5zZWN0 # aWdvLmNvbS9TZWN0aWdvUlNBVGltZVN0YW1waW5nQ0EuY3JsMHQGCCsGAQUFBwEB # BGgwZjA/BggrBgEFBQcwAoYzaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdv # UlNBVGltZVN0YW1waW5nQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5z # ZWN0aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAc9rtaHLLwrlAoTG7tAOjLRR7 # JOe0WxV9qOn9rdGSDXw9NqBp2fOaMNqsadZ0VyQ/fg882fXDeSVsJuiNaJPO8XeJ # OX+oBAXaNMMU6p8IVKv/xH6WbCvTlOu0bOBFTSyy9zs7WrXB+9eJdW2YcnL29wco # 89Oy0OsZvhUseO/NRaAA5PgEdrtXxZC+d1SQdJ4LT03EqhOPl68BNSvLmxF46fL5 # iQQ8TuOCEmLrtEQMdUHCDzS4iJ3IIvETatsYL254rcQFtOiECJMH+X2D/miYNOR3 # 5bHOjJRs2wNtKAVHfpsu8GT726QDMRB8Gvs8GYDRC3C5VV9HvjlkzrfaI1Qy40ay # MtjSKYbJFV2Ala8C+7TRLp04fDXgDxztG0dInCJqVYLZ8roIZQPl8SnzSIoJAUym # efKithqZlOuXKOG+fRuhfO1WgKb0IjOQ5IRT/Cr6wKeXqOq1jXrO5OBLoTOrC3ag # 1WkWt45mv1/6H8Sof6ehSBSRDYL8vU2Z7cnmbDb+d0OZuGktfGEv7aOwSf5bvmkk # kf+T/FdpkkvZBT9thnLTotDAZNI6QsEaA/vQ7ZohuD+vprJRVNVMxcofEo1Xxjnt # XP/snyZ2rWRmZ+iqMODSrbd9sWpBJ24DiqN04IoJgm6/4/a3vJ4LKRhogaGcP24W # WUsUCQma5q6/YBXdhvUwggbsMIIE1KADAgECAhAwD2+s3WaYdHypRjaneC25MA0G # CSqGSIb3DQEBDAUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEplcnNl # eTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1Qg # TmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9uIEF1 # dGhvcml0eTAeFw0xOTA1MDIwMDAwMDBaFw0zODAxMTgyMzU5NTlaMH0xCzAJBgNV # BAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1Nh # bGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDElMCMGA1UEAxMcU2VjdGln # byBSU0EgVGltZSBTdGFtcGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC # AgoCggIBAMgbAa/ZLH6ImX0BmD8gkL2cgCFUk7nPoD5T77NawHbWGgSlzkeDtevE # zEk0y/NFZbn5p2QWJgn71TJSeS7JY8ITm7aGPwEFkmZvIavVcRB5h/RGKs3EWsnb # 111JTXJWD9zJ41OYOioe/M5YSdO/8zm7uaQjQqzQFcN/nqJc1zjxFrJw06PE37PF # cqwuCnf8DZRSt/wflXMkPQEovA8NT7ORAY5unSd1VdEXOzQhe5cBlK9/gM/REQpX # hMl/VuC9RpyCvpSdv7QgsGB+uE31DT/b0OqFjIpWcdEtlEzIjDzTFKKcvSb/01Mg # x2Bpm1gKVPQF5/0xrPnIhRfHuCkZpCkvRuPd25Ffnz82Pg4wZytGtzWvlr7aTGDM # qLufDRTUGMQwmHSCIc9iVrUhcxIe/arKCFiHd6QV6xlV/9A5VC0m7kUaOm/N14Tw # 1/AoxU9kgwLU++Le8bwCKPRt2ieKBtKWh97oaw7wW33pdmmTIBxKlyx3GSuTlZic # l57rjsF4VsZEJd8GEpoGLZ8DXv2DolNnyrH6jaFkyYiSWcuoRsDJ8qb/fVfbEnb6 # ikEk1Bv8cqUUotStQxykSYtBORQDHin6G6UirqXDTYLQjdprt9v3GEBXc/Bxo/tK # fUU2wfeNgvq5yQ1TgH36tjlYMu9vGFCJ10+dM70atZ2h3pVBeqeDAgMBAAGjggFa # MIIBVjAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQU # GqH4YRkgD8NBd0UojtE1XwYSBFUwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQI # MAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAA # MFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VS # VHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRq # MGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1 # c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNl # cnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAbVSBpTNdFuG1U4GRdd8DejIL # LSWEEbKw2yp9KgX1vDsn9FqguUlZkClsYcu1UNviffmfAO9Aw63T4uRW+VhBz/FC # 5RB9/7B0H4/GXAn5M17qoBwmWFzztBEP1dXD4rzVWHi/SHbhRGdtj7BDEA+N5Pk4 # Yr8TAcWFo0zFzLJTMJWk1vSWVgi4zVx/AZa+clJqO0I3fBZ4OZOTlJux3LJtQW1n # zclvkD1/RXLBGyPWwlWEZuSzxWYG9vPWS16toytCiiGS/qhvWiVwYoFzY16gu9jc # 10rTPa+DBjgSHSSHLeT8AtY+dwS8BDa153fLnC6NIxi5o8JHHfBd1qFzVwVomqfJ # N2Udvuq82EKDQwWli6YJ/9GhlKZOqj0J9QVst9JkWtgqIsJLnfE5XkzeSD2bNJaa # CV+O/fexUpHOP4n2HKG1qXUfcb9bQ11lPVCBbqvw0NP8srMftpmWJvQ8eYtcZMzN # 7iea5aDADHKHwW5NWtMe6vBE5jJvHOsXTpTDeGUgOw9Bqh/poUGd/rG4oGUqNODe # qPk85sEwu8CgYyz8XBYAqNDEf+oRnR4GxqZtMl20OAkrSQeq/eww2vGnL8+3/frQ # o4TZJ577AWZ3uVYQ4SBuxq6x+ba6yDVdM3aO8XwgDCp3rrWiAoa6Ke60WgCxjKvj # +QrJVF3UuWp0nr1IrpgxggQtMIIEKQIBATCBkjB9MQswCQYDVQQGEwJHQjEbMBkG # A1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxJTAjBgNVBAMTHFNlY3RpZ28gUlNBIFRpbWUg # U3RhbXBpbmcgQ0ECEQCQOX+a0ko6E/K9kV8IOKlDMA0GCWCGSAFlAwQCAgUAoIIB # azAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIz # MDMxOTA1MTAwOVowPwYJKoZIhvcNAQkEMTIEMAvgTTmUS9eabbAU/Jak9KBhsaRy # bl6Tba+GqwnPLpdNflBz+onVV6w3+TNj+Azn+jCB7QYLKoZIhvcNAQkQAgwxgd0w # gdowgdcwFgQUqzQBOqxAlzGfCBrwsxjhg/gPeIEwgbwEFALWW5Xig3DBVwCV+oj5 # I92Tf62PMIGjMIGOpIGLMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEpl # cnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJV # U1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9u # IEF1dGhvcml0eQIQMA9vrN1mmHR8qUY2p3gtuTANBgkqhkiG9w0BAQEFAASCAgAZ # YBDKdwyHTHSdjSkJmZMmEEhtgpY2UMagcNG3HXNEOBADNVub4rNhQaj0DG6Pl1br # rPrugIcFjkyOGopEsJdIMrIkP6hwt3s0BoeNiLXSAXDuiBdTpNeKFWHjMYs8Yz9C # 0qOigtyjFX04lJ1azvU5qN/Lg8ctOWP3SZnUPP5vKIsqr9EcsSPFcbu8jENiSmb0 # qfTY/sLIuDmACODKlOO9TpwWjUvV1ynYSUOO9GYhi7QoFtO6SC84l6Hn+IZzbGW5 # 2UjSW/SWWZM5MNPzfRC7muR3KZQ7Ahh/Dlpol5IcWON7QiMEaojyWDHBXAsqSDZr # Y+IBbmRc8i++UX0ZcwIjBdwxqfIVwrT76ZON9y5YcxHCg63GLC9DnlQHWwKHSITk # Pa0rEOCKF2G6I7vjf/0Mev8qAxWdWwvObv2zO7PypOHx26EdZZgvBpBuCIpx1pK9 # pkzl/Hjxw0SppJHMdEX155QnztgFHXBQYO9+8UVydXGXskvDniu625ph/DoHxA2e # 5XzfuvrrfVVtC1mEWZZRsx91SGS/WFyD6coKGrLaHAw94YKBNKtQOjKAgo8PXeg5 # DxBOme5EwJg1VilYYurXdEzUoLWvtiJBeD+YDBDi2imGfIGod34OnNBD25RxDXri # E9xGA5y6p1w55eN3buMYwfApYzzI3jncG6Plecj93Q== # SIG # End signature block |