New-Object -ComObject WScript.Shell - User Context

Hi,

I'm trying to create two scripts, a detection and a remediation script to be used with SCCM.

This is to detect if a user profile is missing the Teams icon, created by the machine-wide installer, per user when they first logon.

As below (remediation script):

$ExcludedUserAccounts =  'Administrator','Public','Generic'

$UserProfileDirectories = (Get-ChildItem -Path C:\Users -Exclude $ExcludedUserAccounts).FullName
$TeamsProfileDirectory = '\AppData\Local\Microsoft\Teams'

$Global:NoUpdateEXE = @() # Reset Teams folder to allow Teams to reinstall when user logs back on.
$Global:NonCompliantIcon = @() # Create and set icon as required.
$Global:Compliant = @() # No action required.
$Global:NoTeamsDirectory = @() # No actions as Teams should install at log on.

ForEach ($UserProfile in $UserProfileDirectories)
    {
    
    $RequiredTarget = $UserProfile + $TeamsProfileDirectory + '\update.exe'
    $RequiredArguments = '--processStart "Teams.exe"'

    $Shortcut = New-Object -ComObject WScript.Shell
    $ShortcutLocation = "$UserProfile\Desktop\Microsoft Teams.lnk"
    
    $CurrentTarget = $Shortcut.CreateShortcut($ShortcutLocation).TargetPath
    $CurrentArguments = $Shortcut.CreateShortcut($ShortcutLocation).Arguments
    
    If ( Test-Path ($UserProfile + $TeamsProfileDirectory) )
        {
        If ( Test-Path $RequiredTarget )
            {
            If ( (Test-Path $ShortcutLocation) -and ($CurrentTarget -eq $RequiredTarget) -and ($CurrentArguments -eq $RequiredArguments) ) { $Global:Compliant += $UserProfile }
            Else { $Global:NonCompliantIcon += $UserProfile }
            }
        Else { $Global:NoUpdateEXE += $UserProfile }
        }
    Else { $Global:NoTeamsDirectory += $UserProfile }
    
    }

ForEach ($Item in $NoUpdateEXE)
    {
    If (Get-Process -Name Teams -ErrorAction SilentlyContinue | Where-Object -Property Path -EQ ($Item + $TeamsProfileDirectory + '\Current\Teams.exe')) { }
    Else { Remove-Item -Path ($Item + $TeamsProfileDirectory) -Recurse -Force -Verbose }
    }

ForEach ($Item in $NonCompliantIcon)
    {
    $TargetPath = $Item + $TeamsProfileDirectory + '\update.exe'
    $ShortcutDestination = "$Item\Desktop\Microsoft Teams.lnk"
    $Arguments = '--processStart "Teams.exe"'

    $WshShell = New-Object -ComObject WScript.Shell
    $Shortcut = $WshShell.CreateShortcut($ShortcutDestination)
    $Shortcut.TargetPath = $TargetPath
    $Shortcut.Arguments = $Arguments
    $Shortcut.IconLocation = $Item + $TeamsProfileDirectory + '\Current\Teams.exe,0'
    
    $Shortcut.Save()
    }

The issue is the New-Object -ComObject WScript.Shell section.

One the detection script, I just want to check that the TargetPath and Arguments are set to what they should be. However using New-Object seems to only seems to reference the account PS is running in.

So this code:

    $Shortcut = New-Object -ComObject WScript.Shell
    $Link = Get-Item "C:\Users\tempuser\Desktop\Microsoft Teams.lnk"
        
    $Shortcut.CreateShortcut($Link).TargetPath

I want it to return: 'C:\Users\TempUser\Desktop\Microsoft Teams.lnk'.

But instead it returns: 'C:\Users\LoggedOnUser\Desktop\Microsoft Teams.lnk'.

Tried this under System context and it returned the system profile directory.

Please help PS masters!

Parents
No Data
Reply
  • Every user-based app on a computer including PowerShell always runs in the context of the logged-on user, by design. There is no getting around that.

    Programs have to in order to be associated with all user profile settings/preferences.

    You need a TempUser profile on each target you plan to do this on and be logged on as that user to get what you are after.

    If you are trying o do this remotely, then you cannot run PowerShell code, natively on a remote host as the logged-on user. It is a Windows security boundary. You'd need to leverage the Microsoft SysInternal PSExce tool to run in the user context, locally or remotely. See the PSExec doc on the topic.

    I am not sure why you are doing this TempUser thing, if this is to apply to all logged on users, vs modifying the Windows default user profile for this use case. Thus any new user of a system/any new profile create during startup, will get it from there.

Children
No Data