PowershellFrameworkCollective / psframework

A module that provides tools for other modules and scripts
MIT License
424 stars 41 forks source link

Set-PSFLoggingProvider - PowerShell 7 - A parameter cannot be found that matches parameter name 'FilePath'. #628

Open jpomfret opened 6 months ago

jpomfret commented 6 months ago

Getting errors when using logging code in PowerShell vs Windows PowerShell - I'm unable to add a FilePath for the provider and therefore my scripts aren't logging to files.

This can be replicated by running the following example from the docs https://psframework.org/documentation/quickstart/psframework/logging.html

$paramSetPSFLoggingProvider = @{
    Name         = 'logfile'
    InstanceName = '<taskname>'
    FilePath     = 'C:\Logs\TaskName-%Date%.csv'
    Enabled      = $true
    Wait         = $true
}
Set-PSFLoggingProvider @paramSetPSFLoggingProvider

# Start Logging
Write-PSFMessage "Starting Script"

PowerShell v7.4.1 image

PowerShell v5.1.22621.2506 image

FriedrichWeinmann commented 6 months ago

Heya, thanks for reporting this. Unfortunately, we're at the good old "But it works for me" situation: image Can you provide more context about your 7.4.1 environment? Any particular other modules loaded? Does $error contain any hidden errors from calculating the dynamic parameters of Set-PSFLoggingProvider?

jpomfret commented 6 months ago

output of get-error is below for this session

nothing in $PSDefaultParameters

modules loaded image

I

╰─ff get-error

Exception             :
    Type              : System.Management.Automation.ParameterBindingException
    Message           : A parameter cannot be found that matches parameter name 'FilePath'.
    ParameterName     : FilePath
    TypeSpecified     : string
    ErrorId           : NamedParameterNotFound
    Line              : 1
    Offset            : 24
    CommandInvocation :
        MyCommand        : Set-PSFLoggingProvider
        BoundParameters  :
            Comparer : System.OrdinalIgnoreCaseComparer
            Count    : 4
            Keys     :
                Length : 7

                Length : 4

                Length : 12

                Length : 4
            Values   :

                IsPresent : True

                Length : 10

                Length : 7
            SyncRoot :
                Comparer : System.OrdinalIgnoreCaseComparer
                Count    : 4
                Keys     :
                    Length : 7

                    Length : 4

                    Length : 12

                    Length : 4
                Values   :

                    IsPresent : True

                    Length : 10

                    Length : 7
                SyncRoot :
                    Comparer : System.OrdinalIgnoreCaseComparer
                    Count    : 4
                    Keys     :
                        Length : 7

                        Length : 4

                        Length : 12

                        Length : 4
                    Values   :

                        IsPresent : True

                        Length : 10

                        Length : 7
                    SyncRoot :
                        Comparer : System.OrdinalIgnoreCaseComparer
                        Count    : 4
                        Keys     :
                            Length : 7

                            Length : 4

                            Length : 12

                            Length : 4
                        Values   :

                            IsPresent : True

                            Length : 10

                            Length : 7
                        SyncRoot :
                            Comparer : System.OrdinalIgnoreCaseComparer
                            Count    : 4
                            Keys     :
                                Length : 7

                                Length : 4

                                Length : 12

                                Length : 4
                            Values   :

                                IsPresent : True

                                Length : 10

                                Length : 7
                            SyncRoot :
                                Comparer : System.OrdinalIgnoreCaseComparer
                                Count    : 4
                                Keys     :
                                    Length : 7

                                    Length : 4

                                    Length : 12

                                    Length : 4
                                Values   :

                                    IsPresent : True

                                    Length : 10

                                    Length : 7
                                SyncRoot :
                                    Comparer : System.OrdinalIgnoreCaseComparer
                                    Count    : 4
                                    Keys     : …
                                    Values   : …
                                    SyncRoot : …
        ScriptLineNumber : 1
        OffsetInLine     : 1
        HistoryId        : 70
        Line             : Set-PSFLoggingProvider @paramSetPSFLoggingProvider
        Statement        : Set-PSFLoggingProvider @paramSetPSFLoggingProvider
        PositionMessage  : At line:1 char:1
                           + Set-PSFLoggingProvider @paramSetPSFLoggingProvider
                           + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        InvocationName   : Set-PSFLoggingProvider
        PipelineLength   : 1
        PipelinePosition : 1
    ErrorRecord       :
        Exception             :
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : A parameter cannot be found that matches parameter name 'FilePath'.
            HResult : -2146233087
        CategoryInfo          : InvalidArgument: (:) [Set-PSFLoggingProvider], ParentContainsErrorRecordException
        FullyQualifiedErrorId : NamedParameterNotFound,Set-PSFLoggingProvider
        InvocationInfo        :
            MyCommand        : Set-PSFLoggingProvider
            ScriptLineNumber : 1
            OffsetInLine     : 24
            HistoryId        : 70
            Line             : Set-PSFLoggingProvider @paramSetPSFLoggingProvider
            Statement        : @paramSetPSFLoggingProvider
            PositionMessage  : At line:1 char:24
                               + Set-PSFLoggingProvider @paramSetPSFLoggingProvider
                               +                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    TargetSite        :
        Name          : VerifyArgumentsProcessed
        DeclaringType : System.Management.Automation.CmdletParameterBinderController, System.Management.Automation, Version=7.4.1.500,
Culture=neutral, PublicKeyToken=31bf3856ad364e35
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Data              : System.Collections.ListDictionaryInternal
    Source            : System.Management.Automation
    HResult           : -2146233087
    StackTrace        :
   at System.Management.Automation.CmdletParameterBinderController.VerifyArgumentsProcessed(ParameterBindingException
originalBindingException)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
   at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
   at System.Management.Automation.CommandProcessor.Prepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
--- End of stack trace from previous location ---
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements,
CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
CategoryInfo          : InvalidArgument: (:) [Set-PSFLoggingProvider], ParameterBindingException
FullyQualifiedErrorId : NamedParameterNotFound,Set-PSFLoggingProvider
InvocationInfo        :
    MyCommand        : Set-PSFLoggingProvider
    ScriptLineNumber : 1
    OffsetInLine     : 24
    HistoryId        : 70
    Line             : Set-PSFLoggingProvider @paramSetPSFLoggingProvider
    Statement        : @paramSetPSFLoggingProvider
    PositionMessage  : At line:1 char:24
                       + Set-PSFLoggingProvider @paramSetPSFLoggingProvider
                       +                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
FriedrichWeinmann commented 6 months ago

Get-Error will be default only show the last error. Any surprises when you run this instead?

Get-Error -Newest 3
jpomfret commented 6 months ago

I did just try it on another machine and it worked as expected 🤔

nothing different in Get-Error -Newest 3

FriedrichWeinmann commented 6 months ago

Hm, another test then:

Set-PSFLoggingProvider -Name logfile -

Try tab-menu-completing after typing this far. Assuming things work so far, you should then get a fairly large set of parameters offered: image If that's so, it's some interplay with the other parameters. If you get a truncated list (what I expect), there's a problem with the entire part.

Another thing to check, just in case:

$ExecutionContext.SessionState.LanguageMode

But I think you'd have other errors first if PSFramework were being locked down.

jpomfret commented 6 months ago

Can confirm truncated list image

image

Do you know if something changed with language mode in the last couple of PowerShell releases? I am seeing warnings about that from ohmyposh.

FriedrichWeinmann commented 6 months ago

We did add support for AuditMode in WDAC - a pseudo-CLM where things still work, but get logged what would not have worked. That mode would still report as CLM using that line above.

Fascinating, the entire dynamic parameter system appears broken on your console :( And without error too, which pretty much means there must have been an issue during import, preventing the logging providers from being loaded:

[PSFramework.Logging.ProviderHost]::Providers

This should return an empty dictionary then

jpomfret commented 6 months ago

It does return empty 😢

This seems really weird - opened new powershell session with no profile:

image

FriedrichWeinmann commented 6 months ago

Looks like my module has trouble with this new audit mode Thanks for finding this, I'll need to figure out how to make my validation compatible with that!

jpomfret commented 6 months ago

Appreciate the help troubleshooting this morning - let me know if you need a tester!

FriedrichWeinmann commented 6 months ago

A little background: By the nature of how my logging works, logging providers are executed as trusted mode. Due to this I added some validation, that refuses scriptblocks flagged as CLM. This new audit mode apparently also sets that flag and now my detection blocks incorrectly (it should somehow produce an CLM-audit-error but still run instead). Not going to promise a specific resolution time - I'm aiming for this weekend, but been wrong about that before. Thanks for offering to test it - will get back to you on that if my own testing fails to reproduce.

FriedrichWeinmann commented 2 months ago

Heya @jpomfret - turns out I was a bit optimistic about my own ability to test it (and timeline to fix this). The current version in branch "rsworkflow-extension" - bad branch name, but that happens when you do all your changes in just one branch ... - should have that fixed. Can you do a quick test on that?

jpomfret commented 2 months ago

So... I have got a new laptop since I opened this issue and now on the new one with PowerShell 7.4.3 this works just fine for me... I'll try it on the old laptop tomorrow and see what I can find.