I have a simple powershell script on windows 7 that doesn't work properly. (this is not an issue on XP)
get-psdrive
When I run it directly, I get
Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
A FileSystem A:\
Alias Alias
C 12.30 11.60 FileSystem C:\
cert Certificate \
D FileSystem D:\
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
**Q 1486.63 289.41 FileSystem Q:\**
Variable Variable
WSMan WSMan
When I run this through task scheduler, I get
Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
A FileSystem A:\
Alias Alias
C 12.30 11.60 FileSystem C:\
cert Certificate \
D 开发者_开发知识库 FileSystem D:\
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
Variable Variable
WSMan WSMan
Note that I'm missing my Q: drive. If there's any way to get this resolved, I'll be able to copy files there....
Network drives, and really all drive letters for that matter, are "mapped" to volumes for a given logon session. When you are creating a scheduled task to run it creates a new login session (even if you are currently logged in) and runs the scheduled task in that context. Thus, while you may be logged in and have a Q drive mapped - the second session that is running the task has a completely different environment, Windows is just nice enough to automatically map the C: (and other physical drives) for all sessions.
You shouldn't need to map a map a drive when using PowerShell, other than for perhaps convenience. Unlike the cmd.exe predecessor, PowerShell is perfectly happy to change the current directory to a UNC style path:
cd \\server\share\directory
Is it possible to accomplish what you need without mapping a drive at all? You have mentioned copying files - if the task is running with your credentials, and assuming you have permissions to the Q: drive (lets say \server\share), then your script should be able to do something like:
copy c:\logs\*.log \\server\share\logs
And work just fine without needing to map a drive.
Here is the complete command info for my test that worked. If your environment is different please note how. The task is configured to run as my domain account, only when I am logged in, highest privileges and configured for Windows 7/Server 2008 R2.
The action is to Start a program:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Arguments
-command copy c:\logs\*.log \\server\share\logs
Maybe before running get-psdrive in script, firstly do something like this:
$net = new-object -comobject Wscript.Network
$net.mapnetworkdrive("Q:","\\path\to\share",0,"domain\user","password")
and after doing your job (copying files..):
$net.removenetworkdrive("Q:")
There is a hack if you don't want to have a password in the script, which I prefer to avoid :
- Open your folder with sufficient privileges (domain user for example)
Open a powershell as Administrator and an make a symlink from UNC to local path
New-Item -ItemType SymbolicLink -Path "C:\LocalTemp\" -Value "\unc"
You can now use the UNC path in your powershell script directly, it will open it with the credential provided in the scheduled task.
There is probably some issues with credentials in scheduled tasks, however this is still better in my opinion than password in clear or pseudo obfuscated in scripts.
精彩评论