How do I call a DOSkey Alias from Powershell? - powershell

I have DOSKey Alias that I setup like so (Aliases in Windows command prompt) calling it from the registry, and I'd like to be able to run it from powershell; is there some way to do this? All it really does is add something to the %PATH% environment variable.

If you don't have to use DOSKey and would just like to alias a command, you can use the built-in Set-Alias command like so:
Set-Alias -Name np -Value notepad++
That will, while the current powershell window is open, alias np to notepad++. Which also lets you open files with np temp.txt.
If you'd like to persist that, you could add it to your profile. You can do that by editing your Microsoft.PowerShell_profile.ps1, a shorthand is:
notepad $profile
Feel free to use notepad++ or any other editor you might have in your PATH. You can add the Set-Alias line to the bottom of the file and save and close it.
When you then open another powershell instance, it will have the example np alias available.

Below is code that will copy your DOSKEY macros into PowerShell aliases. This might or might not make sense for some commands which already have PowerShell aliases or do not work in the same way in PowerShell.
Note that you must source the command into the current shell.
PS C:\src\t> type .\Get-DoskeyMacros.ps1
& doskey /MACROS |
ForEach-Object {
if ($_ -match '(.*)=(.*)') {
Set-Alias -Name $Matches[1] -Value $Matches[2]
}
}
PS C:\src\t> . .\Get-DoskeyMacros.ps1
NOTES: (ht mklement0)
This code presumes that the doskey aliases have already been defined, which is not likely in a normal PowerShell session. However, you can start the PowerShell session from a cmd session that has them defined or run a batch file from PowerShell that defines them.
A potential translation-to-alias problem is that doskey macros support parameters (e.g., $*), whereas PowerShell aliases do not.

#lit's script didn't work for me.
Below is a script that worked. It copies the generated Set-Alias commands to the $profile script.
doskey /MACROS |
ForEach-Object {
if ($_ -match '(.*)=(.*)') {
echo ('Set-Alias -Name '+$Matches[1]+' -Value '+$Matches[2])
}
} > $profile
Notes:
Like the original script, this must be executed in a PowerShell session started from a cmd session.
The $profile file didn't exist for me. I first had to create it, along with the containing folder.

Related

doskey to print `$env:Path -split ';'` (in PowerShell), except that doesn't work

Entering $env:path at the prompt correctly returns:
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;...
Entering $env:Path -split ';' at the prompt correctly returns:
C:\WINDOWS\system32
C:\WINDOWS
C:\WINDOWS\System32\WindowsPowerShell\v1.0\
C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps
...
Entering doskey envpath=$env:Path -split ';' at the prompt causes some pretty weird stuff that I've asked elsewhere about cleaning up, but among other things appears to evaluate $env:Path at the time I'm defining the macro.
However the desired result is for it to evaluate $env:Path later, at the time I'm running the macro. How do I create a macro to do that?
Don't try to use doskey.exe in PowerShell: To get it to work at all, you'd have to unload the module that handles interactive command-line editing in PowerShell, PSReadLine - which would take away a lot of useful features. See this answer for background information.
Instead:
Define the desired functionality as a function.
Add that function to your $PROFILE file, so that it is available by default in future PowerShell sessions.
The following demonstrates this technique:
# Make sure the $PROFILE file exists.
if (-not (Test-Path $PROFILE)) {
$null = New-Item -Force $PROFILE
}
# Add the desired functionality as a function definition.
#'
function envpath { $env:Path -split ';' }
'# | Add-Content $PROFILE
Note the use of a (verbatim) here-string (#'<newline>...<newline>'#), which makes embedding a function definition in a string syntactically easier, since no escaping of embedded quote characters is needed.
envpath will then be defined in future PowerShell sessions (unless the session was created with the CLI's -NoProfile switch).

How to save function in powershell?

Hi so i've tried to make my first function. A simple one that will restart powershell in windows terminal. And it's working.
function Restart-PowerShell{
Get-Process -Id $PID | Select-Object -ExpandProperty Path | ForEach-Object { Invoke-Command { & "$_" } -NoNewScope }
But when i restart powershell the function disappear, it doesn't save it. How can i save it? I've tried to look around but couldn't find any way to save
You save PowerShell functions by simply putting their definition in a file on disk:
"function Restart-PowerShell {${function:Restart-PowerShell}}" |Set-Content Restart-PowerShell.ps1
This will write it to a file Restart-PowerShell.ps1 in the current directory.
Next time you need to re-use your function, it's as simple as dot-sourcing the file:
PS ~> . .\path\to\Restart-PowerShell.ps1
PS ~> Restart-PowerShell # now the function is available in the current session
Mathias R. Jessen's helpful answer shows how to save your function's definition to a custom file that you can dot-source on demand in future sessions.
However, there is a file that is dot-sourced automatically when a PowerShell session starts (unless explicitly suppressed with -NoProfile via the PowerShell CLI): your $PROFILE file, and that's where customizations of your sessions - such as custom functions and aliases - are typically stored.
Therefore, if you add your function to your $PROFILE file, it automatically becomes available in future sessions too.
You can open $PROFILE in your text editor or, building on Mathias' technique, add the function programmatically, as follows, which ensures on-demand creation of the file and its parent directory (on a pristine machine, neither exists):
# Make sure the $PROFILE file exists.
If (-not (Test-Path $PROFILE)) { $null = New-Item -Force $PROFILE }
# Append the function definition to it.
#"
function Restart-PowerShell {
${function:Restart-PowerShell}
}
"# | Add-Content $PROFILE
Note: To reload your profile mid-session after having modified $PROFILE, use . $PROFILE.

Powershell - shortened the directory prompt, but how to save the change?

Using Powershell in Windows 10. To change the prompt from:
PS C:\Users\b.HQ\Desktop\tsdev\my_folder>
PS my_folder> tsc
I used the following command in Powershell:
function prompt {'PS ' + $(Get-Location | Split-Path -Leaf) + ">"}
But, each time I restart Powershell, I have to reenter this. Is there any way to persist this change?
P.S. I know nothing about the config of Powershell, and I have looked for a solution, but apart from the prompt I am using, I did not see a way of saving it.
Run powershell as administrator, then run the following:
Test-Path $Profile
if it returns false then no you don’t have a profile file yet, so create it:
New-Item –Path $Profile –Type File –Force
(this will create profile file, or will overwrite the existing one)
Then, edit your profile file:
notepad $Profile
put your function in the file and save.
I created this neat prompt to that shows the drive and last folder.
For you example it would render as
PS C:\Users\b.HQ\Desktop\tsdev\my_folder>
as
PS C:\...\my_folder>
The prompt function is:
function prompt {"PS " + (get-location).drive.name+":\...\"+ $( ( get-item $pwd ).Name ) +">"}

Using powershell to execute cmd commands

I love Linux's terminal. I found a package manager for windows called "Chocolatey" and thought if I combined that and powershell I might just have an alternative to the Linux terminal for windows. However, after installing packages I've found that I can't run them from Power Shell. I can get some of them to work using: & "mycommand"
There are a lot of obvious advantages to using Power Shell over CMD. Little things like "ls" instead of "dir" for example. I would really like to just be able to run cmd commands from power shell and hopefully without extra characters. Is there anyway to do this cleanly?
In Powershell, dir and ls are just aliases to the cmdlet Get-ChildItem
You can add alias with the cmdlet : new-Alias
For example, if you want to add an "grep" alias from the cmdlet Select-String you can run :
New-Alias -name grep -Value Select-String
Powershell can run external executable, even without the &, as long as the executable is located in your PATH environment variable.
Are your external commands located in your PATH ?
To check that, run :
$env:PATH
If not, you can add a path to your PATH environment variable, like so :
$ENV:PATH += ";C:\Path\To\YourPackages\"

Execute shortcuts like programs

Example: You have a shortcut s to SomeProgram in the current directory.
In cmd.exe, you can type s and it will launch the program.
In PowerShell, typing s gives:
The term 's' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.
If you type s.lnk or SomeProgram, it runs the program just fine.
How can I configure PowerShell to execute shortcuts just like programs?
You can also invoke a shortcut by using the "invoke-item" cmdlet. So for example if you wanted to launch "internet explorer.lnk" you can type the following command:
invoke-item 'Internet Explorer.lnk'
Or you could also use the alias
ii 'internet explorer.lnk'
Another cool thing is that you could do "invoke-item t.txt" and it would automatically open whatever the default handler for *.txt files were, such as notepad.
Note If you want to execute an application, app.exe, in the current directory you have to actually specify the path, relative or absolute, to execute. ".\app.exe" is what you would need to type to execute the application.
On my Vista system typing S won't launch a lnk file unless I have the environment variable PATHEXT set with .lnk in the list. When I do. S will work in cmd.exe and I have to do .\S in powershell.
After adding ;.LNK to the end of my PATHEXT environment variable, I can now execute shortcuts even without the preceding ./ notation. (Thanks bruceatk!)
I was also inspired by Steven's suggestion to create a little script that automatically aliases all the shortcuts in my PATH (even though I plan to stick with the simpler solution ;).
$env:path.Split( ';' ) |
Get-ChildItem -filter *.lnk |
select #{ Name='Path'; Expression={ $_.FullName } },
#{ Name='Name'; Expression={ [IO.Path]::GetFileNameWithoutExtension( $_.Name ) } } |
where { -not (Get-Alias $_.Name -ea 0) } |
foreach { Set-Alias $_.Name $_.Path }
I don't believe you can. You might be better off aliasing commonly used commands in a script that you call from your profile script.
Example -
Set-Alias np c:\windows\notepad.exe
Then you have your short, easily typeable name available from the command line.
For one, the shortcut is not "s" it is "s.lnk". E.g. you are not able to open a text file (say with notepad) by typing "t" when the name is "t.txt" :) Technet says
The PATHEXT environment variable
defines the list of file extensions
checked by Windows NT when searching
for an executable file. The default value of PATHEXT is .COM;.EXE;.BAT;.CMD
You can dot-source as described by others here, or you could also use the invocation character "&". This means that PS treats your string as something to execute rather than just text. This might be more important in a script though.
I'd add that you should pass any parameters OUTSIDE of the quotes (this one bit me before) note that the "-r" is not in the quoted string, only the exe.
& "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe" -r | out-null
You can always use tab completion to type "s[TAB]" and press ENTER and that will execute it.