Writing custom Powershell Cmdlet to accept table of data - powershell

I need to write a custom powershell cmdlet in C# that would accept data and be able to enumerate over it. I have followed some examples online and have some working code.
The problem I have can be demonstrated as follows:
I want a custom powershell cmdlet to take that output of another command as input to a parameter, so for example Get-Process
I want my custom cmdlet to accept data in table format
Enumerate over the data
The problem I have is that I am not sure how to setup a parameter to take a table of data in
Not sure how to output data from my cmdlet in table form.
Can anyone provide any examples?

I have no idea what you mean with "table format". In PowerShell you should work with objects (or, of course, lists of objects).
What you want to do, to create a cmdlet which takes the output of one command as it's input, i.e. accepts pipeline input, is to mark one of your parameter to take the value from the pipeline. You can find good instructions on how to do this at the MSDN section on Adding Parameters that Process Pipeline Input.

Related

Error: Parameter set cannot be resolved using the specified named parameters

Trying to write a simple PowerShell script, but got stuck with an error, and I can't find any solution on the web.
$stream = [IO.MemoryStream]::new([Text.Encoding]::UTF8.GetBytes('aaaaaaaaaa!'))
Get-FileHash -InputStream $stream -Algorithm SHA512
AddPnPFile -Path './bundle.json' -Folder "$($FolderRelativeURLGeneral)$($folder)" -Stream $stream
Why am I getting an error for providing a stream to the Stream parameter? Removing the parameter solved the issue, but obviously I want to write something to the file, so can someone tell me how to write content to the file? Do I need to create a filestream out of the stream? However, the documentation doesn't specify that it has to be a file stream. How come it doesn't work?
How to convert a string to a stream object in Powershell?
In PowerShell, a parameter set specifies which parameters can be used together when calling a function.
You can use parameters from one set or another set, you cannot mix and match.
Checking the documentation for Add-PnPFile, Path and Folder are part of one parameter set, while Folder and Stream are part of another; there is no parameter set that has all 3 parameters.
I think you're looking for FileName (which i assume creates a file from the stream) instead of Path (which is a local file path).

How to pass parameters to a Powershell script with UiPath

I am trying to run a powershell script with uipath. I have found two approaches to run it;
Read the script as a text and pass to Invoke Powershell activity
Use Run powershell script activity from Script Activities package
Now I need to pass arguments to the powershell script from uipath. Some have mentioned about formatting the string with parameters and invoking the script.
But, rather than that, think we can directly pass parameters from UiPath.
In Run Powershell script, it has Parameters as input
In Invoke Powershell, it has Parameters under Input section and PowershellVariables under Misc
I have been searching for a while. But still I am unable to figure out how to pass parameters using above activities.
I am trying to send outlook mails using powershell. Still in the process of learning how to work with it. Plz help…
EDIT
Found solution for one approach. Added it as an answer.
Found an answer from this link. Out of the two approaches, it provides a solution to pass the parameters using Invoke Power Shell activity.
Read the .ps1/.txt file containing the script, with Read Text File activity
Call the Invoke Power Shell activity by passing file content as CommandText and parameters in the Parameter collection.
But, it would be great, if I can get to know how to pass parameters using Run power shell script activity.

Logging Powershell Job Results

I have created a powershell interface which essentially collects information and then sends that info to an external PS script via Start-Job. I have a timer that triggers recieve-job every second, and updates an output box with STDOUT from the job I created.
External PS Script:
This script has many functions (which utilize many cmdlets), and will be printing messages via Write-Verbose to a log. The issue is, sometimes in these functions I print messages and/or also return a value.
As we all know, anything that a function returns is placed into standard output. So anytime a function returns a value, that value is printed into the Output Rich Textbox control. I don't want that. Also, if I am using VERBOSE, the message is not being printed in the control (however, it is being printed to the console)
What I want:
Print only messages to my rich text box AND my log file, with no function return values in the stream (unless they are apart of a message itself).
Note: I am re-writing this application from a VB.NET app, to a Powershell Studio app... and I noticed previously this was being done by streaming STD Output into the text box, using a similar external powershell script--except that script was using WRITE-HOST. That doesn't make sense to me, as write-host isn't even supposed to be put into the stream.
Alternative Approach:
I had a working example of letting the Job add to the log itself, and then having the UI run Get-Content -tail 1... This WOULD WORK, except that some of my messages will be printed on more than one line, and it wouldn't pull everything as expected. If anyone has a way for me to get any X number of new lines in the log at all times, let me know. That might be easier than my current approach.
so basically you want to use powershell backwards? functions should only return a value that you want in your actual output stream, anything that should not be returning a value to the stream should either be captured in a variable or sent to Out-Null, if want to provide information on what the command is doing that is what write-verbose is for. and Write-Verbose is working as intended, just like write-host it is not put into the stream.
To answer your question what you should do is rewrite your functions so that they return a single value(or no value at all if that is appropriate), for functions that cannot be rewritten you can suppress their output in your script by either assigning them to a variable(if they must be used later) or simply piping them to Out-Null. anything that is currently being captured in the verbose stream that needs to be a part of your output should also be moved to the standard stream and written with Write-Output, potentially with `If statements wrapped around them if you only want that data on certain runs, however if you really want to combine the verbose stream with the standard stream you can check out the info here - Redirect two or more Powershell streams other than output stream to the same file

How do you specify that a parameter accepts wildcard characters in a custom script cmdlet

When you do Get-Help SomeCommand -Full, under each parameter, after the description, there are some additional parameter properties. One of those properties is 'Accept Wildcard Characters?'. When I create my help information for a custom script cmdlet how do I specify that a parameter accepts wildcards?
In the param section of your script, add the attribute SupportsWildcards().
ex.:
param (
[SupportsWildcards()][String]$variable
)
If you want to be able to do this it will require a few things. First off, you either have to create a .dll file, which you are not doing, or you have to create a module. I am not going to go into all of the ins and outs of creating a module, there are already many well written guides on how to do that out there on the internet that you can go look up.
As a part of your module you can include .XML files that provide Help information similarly to the commented help available for individual scripts. The XML style does have some advantages, such as consistency and some advanced features, but does require more effort. Towards this end I would strongly suggest reading Writing Help for Windows PowerShell Modules, as it will explain where to place your XML files, how to structure them, and required headers and what not.
If it were me I'd probably copy an existing XML help file and edit it to suit my needs for the cmdlet, find and read one of the quick-and-dirty HowTo's about creating a module, and then give up on the idea since it's not worth the effort involved to just add that 'Supports Wildcards' flag (in my opinion) if this all started out just as a basic script with commented help.
But the answer is, create a module and supporting XML based Help file for your cmdlet. With that you can add support for the Accepts Wildcards flag for your parameters.

Powershell script formatting issue

When I run Get-Recipient | ft Name in the console everything looks good,
but when I try it in a script the output is just a list of class names;
Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
How do I fix this? Thankful for any and all help!
//David
The Format-* cmdlets should only be used to control display of data. They should rarely if ever be used inside "library" type scripts or functions, expect maybe when displaying status messages or something. The actual output of a Format-* cmdlet is a bunch of magic objects (the FormatEntryData guys) that direct the Powershell engine on how to do display formatting.
It works in the console because you are not capturing your data, you are just letting it display to the screen.
In your script, you should just return the data as-is, and let the caller decide how to format it, if (s)he wants to. If you want to return back only the Name field, use Select-Object Name to pare away the other fields.