Can view the history of powershell OUTPUTS? - windows

It is easy to view the command history of powershell, but sometimes, one might forget to record some important output of the commands, and wish to have a look back into what was on the screen?
Is the history of outputs automatically saved somewhere?

By default, PowerShell records history of commands, but not their output.
You can request PowerShell to record screen output into a file. Use Start-Transcript and Stop-Transcript for this.
Example
Start-Transcript
'do stuff here'
Get-Service X*
'do some more stuff here'
Stop-Transcript
If you want PowerShell to automatically record all your stuff every time, you can add Start-Transcript in your PowerShell profile (use $PROFILE system variable to find path to your profile script, then add Start-Transcript into it)
By default, a new text file is created every time you start transcript. If you want to keep adding output into the same file, then Start-Transcript -Path C:\ExistingTranscript.txt -Append

Related

how to make a Powershell script avaiable from anywhere

I have a Powershell script I would like to make "public", meaning I want to be able to execute the script from any folder as you can do from the command prompt.
Is this possible?
You can also add an alias in your local powershell profile
Alias Example in profile
Set-Alias hello C:\scriptlocation\script.ps1
Now anytime you type hello, the script.ps1 will run.
More info on the various profiles that the alias can be saved to.
https://devblogs.microsoft.com/scripting/understanding-the-six-powershell-profiles/
You can explore the use of your powershell profile to achieve this. See: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles.
If the script is just a function or some variables, you can copy and paste the content into your profile.
Alternatively, if the script represents a standalone unit of code you want to keep separate, you could import it into your main profile as such:
get-content -path C:\blahblahblah\scriptName.ps1 -raw | invoke-expression
Finally, if you are writing an "advanced" powershell function, or are trying to do things officially, you could investigate the use of powershell modules as a way to export your function. See: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_modules
#Lee_Dailey's answer of adding the script to your path is also viable. If you want to add a lot of scripts, one way to do that is to add a folder like C:/PowershellScripts/, to your path, save your scripts there, and then you'll be able to invoke your .PS1 file from anywhere.
Name the script something meaningful ie: awesome.bat Save it in a dir and add the dir to windows env. Command awesome will be globally available.

How can I get PowerShell current location every time I open terminal from file explorer

I can open PowerShell window in any directory using Windows File Explorer.
I want to run a script every time a new PowerShell window is open and use current directory where it was open in the script.
Using $profile let me for automatic script execution but $pwd variable does not have directory used to open PowerShell window but has C:\WINDOWS\system32. I understand PowerShell starts in C:\WINDOWS\system32, run $profile and next change location used with File Explorer. How can I get file explorer current directory it when my script is executes from $profile or maybe there is another way to automatic execute my script after PowerShell window is open?
Note: The answer below provides a solution based on the preinstalled File Explorer shortcut-menu commands for Window PowerShell.
If modifying these commands - which requires taking ownership of the registry keys with administrative privileges - or creating custom commands is an option, you can remove the NoWorkingDirectory value from the following registry keys (or custom copies thereof):
HKEY_CLASSES_ROOT\Directory\shell\Powershell
HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell
Doing so will make the originating folder the working directory before PowerShell is invoked, so that $PROFILE already sees that working directory, as also happens when you submit powershell.exe via File Explorer's address bar.[1]
Shadowfax provides an important pointer in a comment on the question:
When you hold down Shift and then invoke the Open PowerShell window here shortcut-menu command on a folder or in the window background in File Explorer, powershell.exe is initially started with C:\Windows\System32 as the working directory[1], but is then instructed to change to the originating folder with a Set-Location command passed as a parameter; e.g., a specific command may look like this:
"PowerShell.exe" -noexit -command Set-Location -literalPath 'C:\Users\jdoe'
As an aside: The way this shortcut-menu command is defined is flawed, because it won't work with folder paths that happen to contain ' chars.
At the time of loading $PROFILE, C:\Windows\System32 is still effect, because any command passed to -command isn't processed until after the profiles have been loaded.
If you do need to know in $PROFILE what the working directory will be once the session is open, use the following workaround:
$workingDir = [Environment]::GetCommandLineArgs()[-1] -replace "'"
[Environment]::GetCommandLineArgs() returns the invoking command line as an array of arguments (tokens), so [-1] returns the last argument, assumed to be the working-directory path; -replace "'" removes the enclosing '...' from the result.
However, so as to make your $PROFILE file detect the (ultimately) effective working directory (location) irrespective of how PowerShell was invoked, more work is needed.
The following is a reasonably robust approach, but note that a fully robust solution would be much more complex:
# See if Set-Location was passed and extract the
# -LiteralPath or (possibly implied) -Path argument.
$workingDir = if ([Environment]::CommandLine -match '\b(set-location|cd|chdir\sl)\s+(-(literalpath|lp|path|PSPath)\s+)?(?<path>(?:\\").+?(?:\\")|"""[^"]+|''[^'']+|[^ ]+)') {
$Matches.path -replace '^(\\"|"""|'')' -replace '\\"$'
} else { # No Set-Location command passed, use the current dir.
$PWD.ProviderPath
}
The complexity of the solution comes from a number of factors:
Set-Location has multiple aliases.
The path may be passed positionally, with -Path or with -LiteralPath or its alias -PSPath.
Different quoting styles may be used (\"...\", """...""", '...'), or the path may be unquoted.
The command may still fail:
If the startup command uses prefix abbreviations of parameter names, such as -lit for -LiteralPath.
If a named parameter other than the path follows set-location (e.g., -PassThru).
If the string set-location is embedded in what PowerShell ultimately parses as a string literal rather than a command.
If the startup command is passed as a Base64-encoded string via -EncodedCommand.
[1] When you type powershell.exe into File Explorer's address bar instead, the currently open folder is made the working directory before PowerShell is started, and no startup command to change the working directory is passed; in that case, $PROFILE already sees the (ultimately) effective working directory.
1.open the registry (command:regedit)
2.find out the path \HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command (not \HKEY_CLASSES_ROOT\Directory\Background\shell\cmd\command)
3.the default value should be powershell.exe -noexit -command Set-Location -literalPath "%V"
4.you can change some param,
ps: you change the command to cmd.exe /s /k pushd "%V". if you do so, shift & right button in the explorer will open the cmd, not powershell

command prompt auto write to log file

I have a batch file named very_good02.bat. When I run it, it will show some progress info in command prompt.
I wish to auto write a log file that consists of all this progress information with the file name I keyed (which is very_good02).
I tried to ran it like this : very_good02.bat > very_good02log.txt the process is running in background where I can't see them in command prompt.
If I understand correctly, what you are seeking is a way to "tee" the pipeline to both the console and a log file.
The tee command has been in UNIX/Linux for a long time. No such thing in Windows cmd.exe. But, PowerShell does have Tee-Object. At a PowerShell command prompt, use help Tee-Object -full for more information.
powershell -NoLogo -NoProfile "& .\very_good02.bat | Tee-Object -FilePath 'C:\src\t\very_good02.log'"
Naturally, this is easier if your whole script is in PowerShell and not in cmd script language. You don't have to use PowerShell, but that is the clearly stated direction from Microsoft.
I am reminded that this can, actually, be done in a cmd .bat file script. Not easily, but it can be done. https://www.dostips.com/forum/viewtopic.php?p=32615#p32615 If anyone can do it in a .bat file script, Mr. Benham can.

Dynamically get the powershell script name in scripts help example section

Is there a possibility to dynamically add the .ps1 filename to the scripts help section?
I am trying to put examples in the help section of my script and always show the current filename, in case a customer changes it.
Like this:
<#
.EXAMPLE
.\$name -param1 xxx
\#>
and if i run
get-help .\my_script.ps1 -examples
the output should look like
EXAMPLE
.\my_script.ps1 -param1 xxx
I am not sure if this is possible inside of a comment
but get-help has the possibility to detect the filename
if you run
get-help .\filename.ps1
its name is added to the syntax section
you could also run
get-help .\filename.ps1 | select *
and you'll see that the name is part of the output so maybe this is usable somehow?
thanks
To produce the script's path and filename
$pscommandpath
If you want JUST the filename:
Split-Path -leaf $PSCommandpath

Powershell start transcript error

I am running a powershell script from a batch file:
try {
Start-Transcript -path ("C:\PS\Logs\XXXX_Session_QA_" + (Get-Date).tostring("yyyyMMdd-hhmmss-tt") + ".txt")
<Rest of the Code>
}
catch {
stop-transcript
}
Every time I run the script, I see the error
Error: Transcription has not been started. Use the start-transcript command to start transcription.
I have gone through some or most of the previous posts and the code should work but it isn't triggering at all. The initial log file isn't being created either. Any idea why this could be happening or any help here?
Does the folder structure exist for where you are trying to write the transcript to? According to the documentation, it is required (see italics below):
-Path
Specifies a location for the transcript file. Enter a path to a .txt
file. Wildcards are not permitted. If you do not specify a path,
Start-Transcript uses the path in the value of the $Transcript global
variable. If you have not created this variable, Start-Transcript
stores the transcripts in the $Home\My Documents directory as
\PowerShell_transcript..txt files.
If any of the directories in the path do not exist, the command fails.
https://technet.microsoft.com/library/05b8f72c-ae3b-45d5-95e0-86aa1ca1908a(v=wps.630).aspx
You will also need permission to write to that path of course.
So... if the Start-Transcript cmdlet is throwing an error, you are then catching it in the catch{} block (invisibly) which then executes the Stop-Transcript.
This presumably is what is actually causing the error message: the net result is that you are trying to stop transcription when it never started in the first place.

Resources