Search code examples
powershellspecial-folders

Powershell, Remote Job and special folder access


I am working on some remoting stuff, and i seem to have an issue with environment variables on the remote machine. The code I am using to start the remote job is

Invoke-Command -sessionOption:(New-PSSessionOption -noMachineProfile) -computerName:$machine -argumentList: $filePath –scriptblock {
   param (
      [String]$filePath
   )

   & powershell.exe -noProfile -executionpolicy bypass -file $filePath

} -credential:$credential  -authentication:CredSSP –asJob -jobName:$machine > $null

and the code I am running remotely is

$fileName = "$([Environment]::UserName).log"          
$desktop = [Environment]::GetFolderPath("Desktop")


Write-Host "$desktop\$fileName!"

Now, as I understand it, that last bit of code is actually running on the remote machine, in the context of the user credentials in $credentials. Which I would have expected to result in returning the full path to dummy log file on the user's desktop. However, on the remote machine [Environment]::UserName works fine, but [Environment]::GetFolderPath("Desktop") returns nothing. I have tried all different approaches, with the variable assignment being wrapped in quotes like $fileName, and inline in the Write-Host, etc. All solutions work "locally" but none work on the remote machine, but only the Desktop is an issue. My use case for this remote job is going to require accessing a lot of user special folders, so I am hoping there is something basic here I am missing. otherwise I guess I can just hard code all the paths with $([Environment]::UserName) inlined in the string, but not very elegant when PS offers built in access.

EDIT: Hrm, another bit that seems to work fine locally but not remotely is Balloon Tips. This being my example

    [void[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$path = Get-Process -id $pid | Select-Object -ExpandProperty Path
$balloonTip = New-Object System.Windows.Forms.NotifyIcon 
$balloonTip.icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloonTip.balloonTipIcon = "Info"
$balloonTip.balloonTipText = "Testing, one, two"
$balloonTip.balloonTipTitle = "$([Environment]::UserName)" 

$balloonTip.visible = $true 
$balloonTip.showBalloonTip(0)

Solution

  • Do not use -NoMachineProfile:

    -NoMachineProfile <SwitchParameter>
        Prevents loading the user's Windows user profile. As a result,
        the session might be created faster, but user-specific registry
        settings, items such as environment variables, and certificates
        are not available in the session.
    

    Your command does not run in interactive user session (try [Environment]::UserInteractive), so command can not interact with session by showing dialog windows or balloon tips. If you want to execute some command interactively, then you can use task scheduler:

    Register-ScheduledTask -TaskName NotepadTask `
                           -Action (New-ScheduledTaskAction -Execute Notepad) `
                           -Principal (New-ScheduledTaskPrincipal -UserId TestUser -LogonType Interactive)
    Start-ScheduledTask -TaskName NotepadTask