• PowerShell is made of .NET and the .NET Framework has very good build in Classes to encrypt / decrypt.

    If you do not need PGP i recommend this module which do not need a third party tool:

    Encrypt / Decrypt files with PowerShell using symmetrical encryption

    .Example
    
        #Create Key 
        $key = New-CryptographyKey -Algorithm AES -AsPlainText
    
        # now you can save the key as text elsewhere!
     
        #Encrypt the file 
        Protect-File '.secrets.txt' -Algorithm AES -KeyAsPlainText $key -RemoveSource 
     
        #Decrypt the file 
        Unprotect-File '.secrets.txt.AES' -Algorithm AES -KeyAsPlainText $key -RemoveSource

     

  • Hi Scott Baxter, I think your issue is best discussed in the PowerShell Forum.

    https://4sysops.com/groups/powershell/forum/

    Did you try ?

    Test-WsMan

     

  • Hi Wolfgang!

     

    Thank you for the good article.

     

    In the past I used the "offical" PowerShell install sripts:

    For Linux:

    https://github.com/PowerShell/PowerShell/blob/master/tools/install-powershell.sh

    Run it like so:

    wget https://aka.ms/install-powershell.sh; sudo bash install-powershell.sh -preview; rm install-powershell.sh

    For Windows:

    https://github.com/PowerShell/PowerShell/blob/master/tools/install-powershell.ps1

    Run it like so:

    iex "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI -Preview"

     

    The difference between the installation of the released version (6) versus the Preview (7) version is the -Preview flag.

     

    See also:

    https://www.thomasmaurer.ch/2019/07/how-to-install-and-update-powershell-7/

  • Peter Kriegel's profile was updated 1 month, 3 weeks ago

  • I Think If you convert this Function into a Pipline able Function you do not need the Mutex.

    There for you can use the [CmdletBinding()] plus the "Begin {} Process {} End {}" blocks inside your Function.

    "$($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.'))" + "log.log"

    Points to the Current Path  not the Path of the executing script.
    If a command in the current Process is doing a CD the  the log is written in to the new path!!
    So your Logs can get spreaded over the filesystem.

    Is this intendet?

    For Datetime Format I suggest a UTC time Format.

    if you have servers spread across multiple timezones,
    all your event timestamps MUST be transported in UTC time (as String)
    this UTC MUST be calculated by the sender system and
    cannot be calculated by the receiver system.
    Because only the sender knows his locale timezone setting and dailight savings.

     # create UTC time string HH:mm:ss.mmm-+<UtcOffset.TotalMinutes>
    
    $Now = Get-Date
     "$($Now.ToString('HH:mm:ss.fff'))$([System.TimeZoneInfo]::Local.GetUtcOffset($Now).TotalMinutes.ToString('+0;-#'))"
    
    

    Why do you not use the DebugRecord Object

    and what about the WarningRecord (Write-Warning) and VerboseRecord (Write-Verbose) Objects?

    Here I suggest you use an InputObject Parameter and Examin What Object Type do you process.

    With a Redirection Operator of  *>&1 you can Handle ALL PowerShell Streams in one Function.

    See: about_Redirection

    # will create access denied errors! AND
    
    # Redirect all Streams to success streams
    Get-ChildItem 'C:Windows' -recurse *>&1

    Then a Handler Function can look like this:

    Function Tee-StreamRecords {
    
        [CmdletBinding()]
        param(
    
            <#
                InputObjects which are NOT type of ErrorRecord or WarningRecord or DebugRecord or VerboseRecord or InformationRecord
                are allways passed thru without any further processing
    
                If InputObject is type of ErrorRecord or WarningRecord or DebugRecord or VerboseRecord or InformationRecord
                and if you wish to PassThru the InputObject, the handler has to return the Object !
            #>
            [parameter(Position=0,
    		    Mandatory=$true,
        	    ValueFromPipeline=$true
            )]
            [Object]$InputObject,
            
             # is invoked if InputObject is type of WarningRecord
            [Scriptblock]$WarningHandler,
             # is invoked if InputObject is type of VerboseRecord 
            [Scriptblock]$VerboseHandler,
             # is invoked if InputObject is type of ErrorRecord 
            [Scriptblock]$ErrorHandler,
             # is invoked if InputObject is type of DebugRecord 
            [Scriptblock]$DebugHandler,
             # is invoked if InputObject is type of InformationRecord 
            [Scriptblock]$InformationHandler,
            # is invoked if InputObject is type of ErrorRecord or WarningRecord or DebugRecord or VerboseRecord or InformationRecord 
            [Scriptblock]$AllHandler
        )
    
        Begin{}
        Process{
    
            switch ($InputObject)
             {
                {$InputObject -is [System.Management.Automation.WarningRecord]} {
                   If($WarningHandler) { Invoke-Command $WarningHandler -ArgumentList $InputObject }
                   If($AllHandler) { Invoke-Command $AllHandler -ArgumentList $InputObject }
                }
                {$InputObject -is [System.Management.Automation.VerboseRecord]} {
                    If($VerboseHandler) { Invoke-Command $VerboseHandler -ArgumentList $InputObject }
                    If($AllHandler) { Invoke-Command $AllHandler -ArgumentList $InputObject }
                }
                {$InputObject -is [System.Management.Automation.ErrorRecord]} {
                    If($ErrorHandler) { Invoke-Command $ErrorHandler -ArgumentList $InputObject }
                    If($AllHandler) { Invoke-Command $AllHandler -ArgumentList $InputObject }
                }
                {$InputObject -is [System.Management.Automation.DebugRecord]} {
                    If($DebugHandler) { Invoke-Command $DebugHandler -ArgumentList $InputObject }
                    If($AllHandler) { Invoke-Command $AllHandler -ArgumentList $InputObject }
                }
                {$InputObject -is [System.Management.Automation.InformationRecord]} {
                    If($InformationHandler) { Invoke-Command $InformationHandler -ArgumentList $InputObject }
                    If($AllHandler) { Invoke-Command $AllHandler -ArgumentList $InputObject }
                }
                default {
                   # InputObject seems to be an Object for the succes stream so allways pass it thru
                    $PSCmdlet.WriteObject($InputObject)
                }
             }
        }
        End{}
    }

    Then you can use the redirection like so:

    # log all ErrorRecord Objects to "$env:tempmy.log"
    Get-ChildItem 'C:Windows' -recurse *>&1 | Tee-StreamRecords -ErrorHandler { $Args[0] | Out-File "$env:tempmy.log" }

    For an uptodate version see Github:
    https://github.com/Kriegel/PowerLogging

  • Peter Kriegel became a registered member 1 month, 3 weeks ago