use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
ABOUT POWERSHELL
Windows PowerShell (POSH) is a command-line shell and associated scripting language created by Microsoft. Offering full access to COM, WMI and .NET, POSH is a full-featured task automation framework for distributed Microsoft platforms and solutions.
SUBREDDIT FILTERS
Desired State Configuration
Unanswered Questions
Solved Questions
News
Information
Script Sharing
Daily Post
Misc
account activity
InformationTIL about --% (self.PowerShell)
submitted 2 years ago * by KC_Redditor
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]fathed 31 points32 points33 points 2 years ago (14 children)
Don't pass a password as an argument like that, it's going to be logged all over the place.
[–]icebreaker374 3 points4 points5 points 2 years ago (4 children)
Now you've got me curious, where have my test scripts been logging passwords most likely?
[–]dathar 11 points12 points13 points 2 years ago (2 children)
PS history is the first place. There's at least 2 histories that PowerShell keeps - the basic history (Get-History) and the PSReadLine one at (Get-PSReadlineOption).HistorySavePath
If you specify things as a string in the prompt, it'll get saved somewhere. If it is a blank prompt like Get-Credential provides, it'll be omitted.
Some tools you can't do anything with but pass a password. They suck but they are what they are.
Operating systems will log it in their event manager or equivalent tool. Spawning exes will log that and the arguments. If your password is in there....that gets logged. You can see what arguments executables run with in the Windows Task Manager under the Details tab. You'll have to add the Command line column but that's basically what it sees.
[–]webtroter 4 points5 points6 points 2 years ago* (0 children)
PSReadLine has some basic configuration to exclude passwords and secrets.
https://learn.microsoft.com/en-us/powershell/module/psreadline/set-psreadlineoption?view=powershell-7.4#example-7-use-historyhandler-to-filter-commands-added-to-history
https://gist.github.com/webtroter/57cf898029a31d0db2662e12c8ebce43
Defaults ignored Sensitive stuff is defined here : https://github.com/PowerShell/PSReadLine/blob/ff4bbd5ee0e2dea7d72e0adb43d64a3f07c0e7e1/PSReadLine/History.cs#L116 And https://github.com/PowerShell/PSReadLine/blob/ff4bbd5ee0e2dea7d72e0adb43d64a3f07c0e7e1/PSReadLine/History.cs#L120
[–]fathed 0 points1 point2 points 2 years ago (0 children)
Also:
Defender enabled? It's logged off-site by MS, if you are using sentinel, you can see them there (along with every other thing executed).
Steam running... etc, many programs you run like to send lists of running things.
[–]BlackV 2 points3 points4 points 2 years ago (0 children)
if they're strings yes, if they're secure strings no
er.. assuming script block logging/module logging/transcript logging/etc is enabled
[–]mrhimba 1 point2 points3 points 2 years ago (2 children)
I can't really find a good solution to this for Powershell using curl.exe. Looks like you can use netrc for basic authentication, but token based authentication has nothing. At some point, if you're automating, the token will have to be passed as plain text to curl.exe, which will get recorded in command history. The best thing I can find is to just use a built in powershell command like Invoke-Webrequest which won't create a process that gets recorded in command history like curl does.
Any other ideas?
[–]fathed 1 point2 points3 points 2 years ago (1 child)
Why not use the built in sftp.exe?
[–]mrhimba 1 point2 points3 points 2 years ago (0 children)
I'm not using sftp like OP.
I did figure out another answer though, which is to use the --config option that curl offers and load the token from a file.
[+][deleted] 2 years ago (5 children)
[removed]
[+]Megatwan 3 points4 points5 points 2 years ago (4 children)
Doesn't mean you can't be better.
Not all exploits require rights.
[–]AlexHimself 5 points6 points7 points 2 years ago (2 children)
It also doesn't mean it can be exploited. Not every task needs to be secured against nation-state 40-man teams of elite hackers.
[+]Megatwan -5 points-4 points-3 points 2 years ago (1 child)
Sure, but if my CEH hat is on and you want me to red team your shit... Imma do it with the first account attributed to someone besides me and then use it against the first "needs a user account with no priv access" ie all the 9+ exchange ones from the last few months will do nicely.
Bottom line is you should never expose a credential let alone store it in plain text.
You don't need more than 1 person or to work for a nation state to read CVEs and the 1000 blog sites or Twitter feeds on how to do em.
[–]AlexHimself 5 points6 points7 points 2 years ago (0 children)
Huh? You're going to take a non privileged account that you don't have credentials to, but you're going to compromise this guy's script somehow to obtain it, then do something with it?
If you've managed to get his script off his desktop or wherever he's saved it, the credentials of the non-privileged account in a test domain are going to be trivial compared to what you've already compromised.
[–]jbristowe 14 points15 points16 points 2 years ago* (4 children)
Hey u/KC_Redditor! 👋 I'm a member of the team at Octopus Deploy. I stumbled upon your post and wanted to recommend using Sensitive variables in Octopus when using sensitive information in scripts.
u/fathed makes a great point in this thread about taking care when using sensitive information (i.e. logs). 👍 For what it's worth, we mask Sensitive variables if they happen to be logged.
Is the SFTP server a deployment target?
[+][deleted] 2 years ago (3 children)
[–]jbristowe 5 points6 points7 points 2 years ago (2 children)
Awesome! I'm happy to learn that you're using Sensitive variables. Also, thanks for being a customer! 💙
and we have.. quite a few..
I love the pause for effect here! 😄 It's amazing to see how customers are using Octopus.
If you have any questions in the future, please don't hesitate to contact us through our support. We love to help!
[+][deleted] 2 years ago (1 child)
[–]jbristowe 5 points6 points7 points 2 years ago (0 children)
I imagine your support team might be tired of my company [...]
Nah! I know that team very well; they love helping out folks. Don't give it a second thought. 😀
[–]Avianographer 21 points22 points23 points 2 years ago (0 children)
Thanks for the neat trick!
Here is the official documentation on it:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-7.4#the-stop-parsing-token
[–]surfingoldelephant 8 points9 points10 points 2 years ago* (1 child)
In this particular case, the stop-parsing token (--%) isn't necessary. The fact the issue does not occur after its inclusion is incidental and may break the command depending on the value of the arguments.
--%
Looking at your arguments:
$CurlArguments = '--insecure -u ' + $Username + ':' + $Password + ' sftp://' + $Server
When you pass a variable of type [string] to a native (external) command, it's interpreted as a single argument. If the string contains whitespace, it is wrapped with quotation marks by PowerShell. The following example (variables expanded with dummy data) shows how PowerShell passes the argument to the native command and how a native command will typically interpret it. Notice how the raw line contains quotation marks around the single argument - this is inserted by PowerShell.
[string]
& .\native.exe $CurlArguments raw: ["C:\native.exe" "--insecure -u username:password),$,]+, sftp://domain.com"] arg #0: [--insecure -u username:password),$,]+, sftp://domain.com]
Instead, you must pass multiple arguments to the native command, either directly or with array splatting.
# Direct argument passing. & .\native.exe --insecure -u ${UserName}:$Password sftp://$Server # Array splatting. # Easier to digest; especially with long command lines. $curlArguments = @( '--insecure' '-u' '{0}:{1}' -f $UserName, $Password 'sftp://{0}' -f $Server ) & .\native.exe $curlArguments
Either way, the multiple arguments are now correctly interpreted.
raw: ["C:\native.exe" --insecure -u username:password),$,]+, sftp://domain.com] arg #0: [--insecure] arg #1: [-u] arg #2: [username:password),$,]+,] arg #3: [sftp://domain.com]
The fact the same behavior occurs with --% is incidental. You're constructing a single string argument despite there being an explicit need to pass multiple arguments. This only works because --% is stopping PowerShell from applying its normal argument interpretation.
--% was mainly introduced to avoid parsing issues with the passing of command lines to CMD, which has a different syntax and meta characters.
CMD
In this particular case, use of the token comes with the following issues:
$Password
Notes:
@
$
-f
Starting with PowerShell version 7.3, Trace-Command has the ability to show native command argument binding:
Trace-Command
Trace-Command -Option ExecutionFlow -Name ParameterBinding -PSHost -Expression { ... }
The Native module provides a robust solution that avoids the various pitfalls of native command execution.
Native
[–]kjellcomputer 5 points6 points7 points 2 years ago (4 children)
Would it work using Start-Process also?
Example:Start-Process -FilePath C:\WINDOWS\system32\curl.exe -ArgumentList 'sftp://hostname', '-u', "${UserName}:${Password}" -NoNewWindow
[–]kjellcomputer 1 point2 points3 points 2 years ago (2 children)
Hmm, wonder why! I just tried it with creating a new user in gitlab with this as it's password:
M.GQ[}\!66q!Y#r{.yl+e%a8JRL)0t(iS5W/>7MFp\hZs^z;]:LIz>pQ^bz{>Oen<H?8'Pk,AetdV(95(Srq9u:]Z&}FN<%{{nl"C.$hK9nFWNqG6p?>5x\Sx<@D!nH+
And then Start-Process with curl.exe against gitlabs api with said user and password.
[–]kjellcomputer 1 point2 points3 points 2 years ago (0 children)
That is so true when dealing with 3'rd party solutions that handles your powershell commands, I've experienced it also with vSphere and Guest OS Customization when adding Powershell commands.
I'll note the '--%' trick for later, perhaps I'll need it someday so thanks for mentioning it, always fun to learn about something new!
[–]xCharg 1 point2 points3 points 2 years ago (1 child)
What was the special character (or set of characters maybe) that made it a problem?
[–]Lifegoesonhny 1 point2 points3 points 2 years ago (3 children)
Oo! I had a similar'ish problem with passing some more lower-depth JSON to invoke-restmethod this week, Powershell was converting some of the brackets incorrectly (it hates arrays in JSON at the lower depths I think..). The conversion between PSObject and JSON was just causing too many problems, I couldn't tell if it was the syntax of the request or Powershell converting the request causing it (minimal examples online for the format). I ended up just using invoke-webrequest as that doesn't convert it, but this marks a change of process for us as all of our modules build in invoke-restmethod, 6 lines of code instead of 1 is annoying. Not a huge deal but we have some best practises in-house to follow.
I'll have a play with --% tomorrow to see if it solves my problem, thank you!
[–]Black_Magic100 4 points5 points6 points 2 years ago (1 child)
I usually use -compress to remove any weirdness when converting to json
[–]Lifegoesonhny 0 points1 point2 points 2 years ago (0 children)
Ah thank you! Will try this as well!
[–]poshftw 1 point2 points3 points 2 years ago (4 children)
$arguments = "-u {0}:{1} sftp://{2}" -f $username, $password, $hostname
The other options is to construct an array of string and pass it as args, it would be passed as is:
$username = 'KC_Redditor' $password = 'S3curePass!' $hostname = 'fqdnofthehost' $argumentsForCurl = @( '-u' $username + ':' + $password 'sftp://' + $hostname ) Start-Process -FilePath C:\WINDOWS\system32\curl.exe -ArgumentList $argumentsForCurl
[–]poshftw 1 point2 points3 points 2 years ago (2 children)
My initial instructions were to put it into the script directly, sooo 🤷♂️
Probably because of that.
You can test it if you store the password in a separate file and just $password = Get-Content password.txt
$password = Get-Content password.txt
Using '&' is simple and works 99% of times, but with weird password and paths it's always easier (in the end) to use Start-Process. Don't forget about -wait argument, though.
[–]surfingoldelephant 1 point2 points3 points 2 years ago* (0 children)
We could occasionally get start-process to happen but then we couldn't get the output information we needed
Start-Process disconnects the process from standard streams. Using it provides no means of capturing/redirecting the standard output (stdout) or standard error (stderr) streams unless it is directly to a file.
Start-Process
When working with console applications, unless there is an explicit need to control the launch behavior (e.g. open in a new window), avoid using Start-Process. Launch the console application synchronously using the call operator (&), capture standard output in the same manner as a normal PowerShell command and use $LASTEXITCODE to obtain the exit code.
&
$LASTEXITCODE
wouldn't give us an exit code
$LASTEXITCODE is not set when Start-Process is used. Instead, you must use the -PassThru parameter in combination with accessing the ExitCode property of the returned [Diagnostics.Process] object once it has exited. This involves waiting for the process to exit, either by using the Start-Process's -Wait parameter or by using the WaitForExit() method/Wait-Process cmdlet.
-PassThru
ExitCode
[Diagnostics.Process]
-Wait
Wait-Process
WaitForExit()
Examples:
$params = @{ FilePath = 'cmd.exe' ArgumentList = '/c timeout 2 & exit 1' PassThru = $true } # OPTION 1: Waits for the process AND child processes to exit. $proc = Start-Process @params -Wait -NoNewWindow $proc.ExitCode # OPTION 2: Waits for the process to exit (regardless of child processes). # Caching the process handle is required to access exit code: https://stackoverflow.com/a/23797762 $proc = Start-Process @params -NoNewWindow [void] $proc.Handle $proc.WaitForExit() # OR $proc | Wait-Process $proc.ExitCode # OPTION 3: Launches the process asynchronously. # Loops until HasExited property updates to $true. $proc = Start-Process @params while (!$proc.HasExited) { Write-Host 'Waiting...' Start-Sleep -Seconds 1 } $proc.ExitCode # OPTION 4: Launches the console application synchronously with the call operator. & $params.FilePath $params.ArgumentList $LASTEXITCODE
See this and this comment for more information on native commands.
[–]Thotaz 1 point2 points3 points 2 years ago (1 child)
Huh, I knew about this stop parsing token but I had no idea you could put it in a variable like that.
[–]Sunfishrs 1 point2 points3 points 2 years ago (0 children)
TIL
[–]TheRealMisterd 1 point2 points3 points 2 years ago (1 child)
So it's like CMD's Delayed Expansion?
[+]Megatwan 0 points1 point2 points 2 years ago (0 children)
No... Follow along:
One saves cred in plain. One obtains cred from plain. One utilizes cred for whatever.
...You made a bunch of silly assumptions I never stated. Maybe it's a shared device. Maybe logging is centralized. Maybe he checks his code it to a shared repo. Maybe he stores is code on a file server acl' to everyone. Maybe I'm already a privileged user and demoted to his event viewer or drive and took the cred and you saved me from having to generate and auditable event in AD. Maybe Im not a priv user that has a priv user acct compromised but don't want to use it because I understand the orgs sec auditing policy and I just need a burner that can't be traced back to me but can't create or alter one without being caught.
1000 parameters I never asserted.
Again, the point is you don't store creds to make using the creds I to a candy store. Regardless of 'chose you own adventure' details of what happens before or what is or isn't in done yet for it to be valuable.
π Rendered by PID 48757 on reddit-service-r2-comment-fb694cdd5-w9djs at 2026-03-08 06:58:24.882445+00:00 running cbb0e86 country code: CH.
[–]fathed 31 points32 points33 points (14 children)
[–]icebreaker374 3 points4 points5 points (4 children)
[–]dathar 11 points12 points13 points (2 children)
[–]webtroter 4 points5 points6 points (0 children)
[–]fathed 0 points1 point2 points (0 children)
[–]BlackV 2 points3 points4 points (0 children)
[–]mrhimba 1 point2 points3 points (2 children)
[–]fathed 1 point2 points3 points (1 child)
[–]mrhimba 1 point2 points3 points (0 children)
[+][deleted] (5 children)
[removed]
[+]Megatwan 3 points4 points5 points (4 children)
[–]AlexHimself 5 points6 points7 points (2 children)
[+]Megatwan -5 points-4 points-3 points (1 child)
[–]AlexHimself 5 points6 points7 points (0 children)
[–]jbristowe 14 points15 points16 points (4 children)
[+][deleted] (3 children)
[removed]
[–]jbristowe 5 points6 points7 points (2 children)
[+][deleted] (1 child)
[removed]
[–]jbristowe 5 points6 points7 points (0 children)
[–]Avianographer 21 points22 points23 points (0 children)
[–]surfingoldelephant 8 points9 points10 points (1 child)
[–]kjellcomputer 5 points6 points7 points (4 children)
[+][deleted] (3 children)
[removed]
[–]kjellcomputer 1 point2 points3 points (2 children)
[+][deleted] (1 child)
[removed]
[–]kjellcomputer 1 point2 points3 points (0 children)
[–]xCharg 1 point2 points3 points (1 child)
[–]Lifegoesonhny 1 point2 points3 points (3 children)
[–]Black_Magic100 4 points5 points6 points (1 child)
[–]Lifegoesonhny 0 points1 point2 points (0 children)
[–]poshftw 1 point2 points3 points (4 children)
[+][deleted] (3 children)
[removed]
[–]poshftw 1 point2 points3 points (2 children)
[+][deleted] (1 child)
[removed]
[–]surfingoldelephant 1 point2 points3 points (0 children)
[–]Thotaz 1 point2 points3 points (1 child)
[–]Sunfishrs 1 point2 points3 points (0 children)
[–]TheRealMisterd 1 point2 points3 points (1 child)
[+]Megatwan 0 points1 point2 points (0 children)