I have the following Powershell function to set a directory, nice and simple. When i type dev, auto complete works for the items inside the directory..
Example: dev ./project
However when pressing enter, the directory changes to the set-location 'E:\OneDrive\Website Workspace\', not it's child 'E:\OneDrive\Website Workspace\project'.. How would i go about this correctly.
function dev {
set-location 'E:\OneDrive\Website Workspace\'
}
Why don't you use PS drives
New-PSDrive -Name ws -PSProvider filesystem -Root 'E:\OneDrive\Website Workspace\'
get-childitem ws:\project
You just have to put the first line into you profile.
Related
My Powershell script:
New-PSDrive -Name J -Root \\myserver\mypath -PSProvider FileSystem
"test" | Out-File J:\test.txt
Get-Content -Path J:\test.txt
notepad J:\test.txt
J drive maps ok, the file gets created, Get-Content can read it BUT notepad (or any .exe) cannot see the file.
What should I do to make the drive mapping visible to other executables run within the script?
Thanks.
New-PSDrive by default creates drives that are visible only to PowerShell commands, in the same session.
To create a regular mapped drive that all processes see, use the -Persist switch, in which case you're restricted to the usual single-letter drive names (such as J: in your example).
Note: Despite the switch's name, the resulting mapping is only persistent (retained across OS sessions) if you either invoke it directly from the global scope of your PowerShell session (possibly by dot-sourcing a script that contains the New-PSDrive call from there) or explicitly use -Scope Global.
Otherwise, the mapping goes out of scope (is removed) along with the scope in which it was defined.
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
I'm trying to create a D: drive in Windows, which points to some local directory (e.g. C:\DDrive) using PowerShell.
This code runs fine:
New-PSDrive -Name D -Root "C:\D_Drive\" -PSProvider "FileSystem"
But in the Windows Explorer no D:-drive is visible.
How does one use that command correctly?
Also: the drive should be permanent, so I tried adding a "-Persist" parameter. But that leads to an error ("unknown parameter "-Persist"...").
Just run:
subst D: "C:\D_Drive\"
in non-elevated PS session (don't run as Administrator).
The New-PSDrive command only creates a mapping that is visible in PowerShell. It's not shown in explorer at all.
Here are two other questions that ask the same thing:
https://community.spiceworks.com/topic/649234-powershell-mapped-drive-not-showing-in-my-computer
https://social.technet.microsoft.com/Forums/windowsserver/en-US/96222ba2-90f9-431d-b05a-82b804cdc76e/newpsdrive-does-not-appear-in-explorer?forum=winserverpowershell
I'd like a simple command to copy a shortcut for Devices and Printer.lnk to All Users Profile Start Menu so that I can pin this shortcut to every users start menu that logs in to the Windows 10 PC at logon.
I've exported my start menu but having read up on it doesn't seem possible to pin the Devices and Printers shortcut in the normal fashion. This is why I've uploaded the shortcut to a network location that all users have access to, if I can copy this to a location on the PC that all users have access to then I can adjust my startmenu script so that it appears as a tile.
I can copy the shortcut to a basic location (the logged on user) but not to all users folder?
I thought that the following would work but doesn't:
Copy-Item -Path "\\Server\Share\*.lnk" -Destination "$env:allusersprofile\APPDATA\Microsoft\Windows\Start Menu\Programs"
Appreciate your help.
Edit: I have resolved the above issue however, it's lead me on to a follow on issue. I apply this script when a user logs in to Windows 10 but I then want to run a separate task (that is a part of the same ps1 file) which removes a whole host of Bloatware from the OS.
I've tried to add a ; and additionally and but they both still require the user to login twice to complete both tasks. My full script at the moment is:
Copy-Item -Path "\\Server\Share\*.lnk" -Destination "$env:APPDATA\Microsoft\Windows\Start Menu\Programs"; $AppList = #( "*Microsoft.3dbuilder*" etc etc*" ) foreach ($App in $AppList) { Get-AppxPackage -Name $App | Remove-AppxPackage -ErrorAction SilentlyContinue }
I've added "etc etc" as there's a load of commands below that I won't include that remove the bloatware.
You need to remove APPDATA from Destination and it should work. Use following code:
Copy-Item -Path "\\Server\Share\*.lnk" -Destination "$env:ALLUSERSPROFILE\Microsoft\Windows\Start Menu\Programs"
I am using dir \\pwdf1280\rep\"*.txt" /S to search for all the txt files in the folder rep. I used the /S argument to search for the same in the sub directories, but the problem is the command runs forever. I am basically writing a perl script which has to find these files along with their timestamp.
Is there any other approach to solve this, or can I improve on the above command?
The problem is the dir command I mentioned above runs forever and does not display files present in rep's sub directories. It just displays files present in rep directory. I want to search for a file in the rep's sub directories.
One way that might speed the process up is to run the directory search on the remote machine using PowerShell.
C:\src\powershell> type .\rc001.ps1
Invoke-Command `
-ComputerName 'pwdf1280' `
-Command { Get-ChildItem '\\pwdf1280\rep' -Recurse -Filter '*.txt' } |
ForEach-Object { $_.FullName }
Then, from a cmd script run:
C:\src\powershell> powershell -NoProfile -File .\rc001.ps1
Alternatives might be to run the dir command remotely using psexec from SysInternals or plink from PuTTY.