4

I'm trying to send an e-mail with a powershell-function using the cmdlet send-mailmessage. I need to modify the encoding of the text. The cmdlet send-mailmessage has a parameter "encoding" which uses the class System.Text.Encoding. So I have to use something like this:

Send-Mailmessage -Encoding ([System.Text.Encoding]::UTF8)

I'd like to use -Encoding UTF8 instead. The Out-File cmdlet works like this. How can I reproduce the behaviour from the Out-File cmdlet?

That's my idea but I find it a bit circumstantial:

[parameter()][ValidateSet("UTF8","Unicode","ASCII")][String]$Encoding

With this I would create the encoding accordingly.

[System.Text.Encoding]::$Encoding

1 Answer 1

2

You can create a proxy function, change the type of the Encoding parameter to System.String and manipulate it in the Begin block. I included this example in the PowerShell Proxy Extensions module.

function Send-MailMessage
{
    [CmdletBinding()]

    param(
        [Parameter(ValueFromPipeline=$true)]
        [Alias('PsPath')]
        [ValidateNotNullOrEmpty()]
        [System.String[]]
        ${Attachments},

        [ValidateNotNullOrEmpty()]
        [System.String[]]
        ${Bcc},

        [Parameter(Position=2)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        ${Body},

        [Alias('BAH')]
        [Switch]
        ${BodyAsHtml},

        [Parameter()]
        [ValidateSet('ASCII','UTF8','UTF7','UTF32','Unicode','BigEndianUnicode','Default','OEM')]
        [ValidateNotNullOrEmpty()]
        [Alias('BE')]
        [System.String]
        $Encoding,

        [ValidateNotNullOrEmpty()]
        [System.String[]]
        ${Cc},

        [Alias('DNO')]
        [ValidateNotNullOrEmpty()]
        [System.Net.Mail.DeliveryNotificationOptions]
        ${DeliveryNotificationOption},

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        ${From},

        [Parameter(Position=3)]
        [Alias('ComputerName')]
        [ValidateNotNullOrEmpty()]
        [System.String]
        ${SmtpServer},

        [ValidateNotNullOrEmpty()]
        [System.Net.Mail.MailPriority]
        ${Priority},

        [Parameter(Mandatory=$true, Position=1)]
        [Alias('sub')]
        [ValidateNotNullOrEmpty()]
        [System.String]
        ${Subject},

        [Parameter(Mandatory=$true, Position=0)]
        [ValidateNotNullOrEmpty()]
        [System.String[]]
        ${To},

        [ValidateNotNullOrEmpty()]
        [System.Management.Automation.PSCredential]
        ${Credential},

        [Switch]
        ${UseSsl}
    )


    begin
    {
        try 
        {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
            {
                $PSBoundParameters['OutBuffer'] = 1
            }

            if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Encoding')) 
            {
                $null = $PSCmdlet.MyInvocation.BoundParameters.Remove('Encoding') 
                $newValue = & {
                    if ($Encoding -eq 'OEM') 
                    {
                        [System.Text.Encoding]::GetEncoding($Host.CurrentCulture.TextInfo.OEMCodePage)
                    }
                    else
                    {
                        [System.Text.Encoding]::$Encoding
                    }
                }

                $null = $PSCmdlet.MyInvocation.BoundParameters.Add('Encoding',$newValue)
            }


            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Send-MailMessage', [System.Management.Automation.CommandTypes]::Cmdlet)
            $scriptCmd = {& $wrappedCmd @PSBoundParameters }
            $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
            $steppablePipeline.Begin($PSCmdlet)
        }
        catch 
        {
            throw
        }
    }

    process
    {
        try 
        {
            $steppablePipeline.Process($_)
        } 
        catch 
        {
            throw
        }
    }

    end
    {
        try 
        {
            $steppablePipeline.End()
        } 
        catch 
        {
            throw
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Err, that was kind of my idea. I still find it a bit circumstantial. But if this is the only way I'll accept your answer.
I don't know of any other way to do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.