Powershell Startup Script GPO Not Applying - powershell

Pretty basic script used to create a web shortcut on the PC's desktop, but it's not applying for some reason. I have it set in the gpo under
Computer Configuration->Policies-> Windows Settings-> Scripts-> Startup->
Added the powershell script-> And set it to run the powershell script first.
I also know the script works because I have tried running it manually on the machine without admin privileges or anything and it appears just fine.
$DesktopPath = [Environment]::GetFolderPath("Desktop") + "\Prophet21.url"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($DesktopPath)
$Shortcut.TargetPath = "https://p21.gallagherseals.com/prophet21/#/login" $Shortcut.Save()

You're running the code in the wrong context, to run as a user and affect a user, you need to deploy this as a User Configuration.
When you run a Startup Script for a Computer, this happens when the PC is Domain Joined and will process shortly after displaying the initial login screen silently in the background.
But because there is no user logged in yet, some items aren't available.
To fix this, just deploy it as a User Configuration, the full path to the setting would be:
User Configuration -> Policies -> Windows Settings -> Scripts (Logon / Logoff);
The better approach
However, GPO also natively supports creating Desktop Icons with a nice and easy to use wizard. Just follow this short guide by Praj Dasai. I used to manage GPO and I would always prefer a native solution to running a script.

Related

Start-Process, set focus (?) and press key on virtual machine disconnected from RDP

I have a situation which I need some help with.
I'm running an Azure build pipeline on microsoft hosted private VM with quite a old build program/IDE which does not have any CLI.
So I have to start the program and then press a key (F10) to start the build, right now i'm using Powershell for this.
I have issues though to get this to work on the VM when I have disconnected RDP, almost always (not 100%) when I have rdp open my script works and set focus to the program and presses the key. But sometimes it doesn´t work, and it seems to always fail when the rdp is disconnected. My build fails and when I connect with RDP the window is just grey:d out and it hasn't registered any keypress.
I have found some similar threads which seems to touch upon the issue, but not any solution for Powershell.
Setting focus to window in a virtual machine
Sendkeys On Disconnected RDP Session
One solution seems to be to redirect standard input to the started program which means we don't have to care about focusing the window, but how do I redirect a keypress to a started process with Powershell? (Any other scripting language available in azure pipelines yaml is also ok)
The best solution so far has been
param
(
[string]$appName,
[string]$key
)
$objShell = New-Object -ComObject wscript.shell
$proc = Get-Process $appName
$objShell.AppActivate($proc.Id)
Start-Sleep -Seconds 1
$keyString = "'{" + $key + "}'"
$objShell.SendKeys($keyString)
But as stated, this seems to only work when I have an active RDP connection (and not 100% of the time). I have also tried using SetForegroundWindow which works fine when I run the script on my own computer but not on the VM.
Many thanks
Carl

Remote execution of powershell script with autosys - to interact with IE _ComObject

I have a Powershell script designed to automate the testing of some URLs. The script invokes an Internet Explorer session as such:
$IEProcess = Start-Process -FilePAth 'C:\Program Files (x86)\Internet Explorer\iexplore.exe' -ArgumentList "-private $url"
$Shell = New-Object -ComObject Shell.Application
$IE = $Shell.Windows()
It then proceeds to use the $IE object to navigate to different URLs, perform various checks against the pages HTML document bodies and take screenshots of the resulting web pages. Ultimately, the IE session is ended and the screenshots are distributed via email as attatchments.
The script works perfectly when logged onto the virtual host-machine with a service account, that has the necessary permissions for single-sign-on to the various URLs. However, the requirement is for the script to run remotely as a scheduled task, on a daily basis. There should be no interaction by a user other than opening the resulting email.
I have had a job set up in AutoSys to execute the script remotely, once a day, with highest privileges; but the script fails to complete as expected. Specifically, the .Windows() method fails passing the following error message:
Exception calling "Windows" with "0" argument(s): "The server process could not
be started because the configured identity is incorrect. Check the username an
d password. (Exception from HRESULT: 0x8000401A)"
I have to give the job of scheduling the task in autosys to someone else (for security reasons) but I trust that they have configured the job with the appropriate username/password for the necessary service account.
Some online sources suggest to me that the issue might lie with trying to use _ComObjects remotely, and that instances of Internet Explorer require an interactive user session with a UI - which isn't standard config for an autosys batch job.
I have had my autosys-guy add a flag to the job description which should make the user session "interactive", but the script still doesn't execute correctly.
I'm looking for some general insight on the topic and hopefully a solution to get the job running. If anyone cares to help me out I would greatly appreciate it! :)
I also have a more focussed question:
Even if I managed to get a handle on the IE session, should I expect the screenshots that the script takes to fail since the screen buffer for the VM has no monitor to render to? - The images are bitmap and refer to the IE shell objects "position", "width" and "height" for capture placement/dimensions; which presumably mean nothing without a screen resolution??
Thank you for taking the time to read my issue!

Need help working with comaddins.connect

I have created a script that will activate an Outlook Add-in if it is not currently active in the ribbon. This is done by changing the boolean setting on comaddin.connect from false to true. The script only works under certain conditions.
Basically, the issue I've come across is that when you run new-object -comobject Outlook.Application, it will only work if the shell is open in the same mode as Outlook (if Outlook is currently open, which it needs to be). Since the add-in was installed to all users, the boolean setting I need to change is in HKLM which requires the powershell window to be ran in administrator mode. So, I can't work with the Outlook comobject if the shell is in administrator mode, but I can't change the setting I need unless the shell IS in administrator mode.
Note: The below code works if Outlook and the shell are both ran in administrator mode, or if the add-in is uninstalled and reinstalled under the current user only. It doesn't work with the add-in installed to all users, which is what we need unfortunately.
I'm hoping someone out there has a creative way around this! :)
$objoutlook = New-Object -ComObject outlook.application
$objoutlook.application.COMAddIns | where {$_.description -eq "Addin Name Here"} | %{$_.connect=$true}
There is nothing you can do about that, it's a catch-22. the real solution would be for the COM addin itself to hide or show its UI appropriately while staying active at all times.

Popup message for current user after script powershell

I created PowerShell script wich install an application on computer (windows 7).
This script is in GPO and deployed with GPO at logon users. This worked fine, but I want that at the end of installation, my powershell script send at the current logged user on computer a message like "Reboot your computer please".
I tested many things but I don'tview popup, maybe because my script are execute with admin rights (not with user rights).
Test :
#$wshell = New-Object -ComObject Wscript.Shell
#$wshell.Popup("Operation Completed",0,"Done",0x1)
[Windows.Forms.MessageBox]::Show(“My message”, , [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Information)
Your script may be popping up the message but then closing the PowerShell console immediately after, removing the popup. Try waiting on the result of the popup before closing the PowerShell instance:
$wshell = New-Object -ComObject Wscript.Shell
$result = $wshell.Popup("Operation Completed",0,"Done",0x1)
You need to load the assembly providing the MessageBox class first, and you cannot omit the message box title if you want to specify buttons and/or icons.
Add-Type -Assembly 'System.Windows.Forms'
[Windows.Forms.MessageBox]::Show(“My message”, "", [Windows.Forms.MessageBoxButtons]::OK, [Windows.Forms.MessageBoxIcon]::Information)
# ^^
You can use an empty string or $null here, but simply not providing a value (like you could do in VBScript) is not allowed.
As a side-note, I'd recommend avoiding typographic quotes in your code. Although PowerShell will tolerate them most of the time, they might cause issues sometimes. Always use straight quotes to be on the safe side.
Edit: Since you're running the script via a machine policy it cannot display message boxes to the logged-in user, because it's running in a different user context. All you can do is have a user logon script check whether the software is installed, and then display a message to the user. This works, because a user logon script running in the user's context.

Get currently logged in users with powershell to add shortcut to desktop

I have a script that I deploy using LANDesk and in the script it calls a powershell script to add a shortcut to a network folder on the user's desktop. LANDesk logs in to run the script with a local machine account but I don't want the shortcut to be put on that desktop but of the desktop of the user that is currently logged in. Is there a way to do this in powershell?
Here is my code for adding the shortcut if you run the script as the logged in user (can't run as the user themselves because they don't have admin rights)
$wshshell = new-object -comobject WScript.Shell
$Ink = $wshshell.CreateShortcut("$home\Desktop\PI_Users.lnk")
$Ink.TargetPath = "\\htntfs04\PI_Users"
$Ink.Save()
Thanks in advance for help.
If you're using LANDesk, and you're using a package to distribute the script, you can choose between executing the script as LocalSystem which is the default, or as the Current user's account.
Just open the properties of the package, go to Accounts and choose "Current user's account". The task will fail if there's no user logged in to the machine.
But, if I understand correctly, the problem is that the user is not allowed to create a link on its own desktop? If so, this solution won't work and the task would fail anyway!
Another approach I often use would be to execute a script that loops through all the local profiles and creates a link on the desktop of each user. If it's okay for you to use a WSH script instead of a powershell script, you could use something like this:
Const HKEY_LOCAL_MACHINE = &H80000002
Set objRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv")
Set ws = CreateObject("Wscript.Shell")
strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubkeys
For Each objSubkey In arrSubkeys
strValueName = "ProfileImagePath"
strSubPath = strKeyPath & "\" & objSubkey
objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE, strSubPath, strValueName, strProfile
If Left(strProfile, Len(ws.ExpandEnvironmentStrings("%windir%"))) <> ws.ExpandEnvironmentStrings("%windir%") Then
Set objShtCut = ws.CreateShortcut(strProfile & "\Desktop\PI_Users.lnk")
objShtCut.TargetPath = "\\htntfs04\PI_Users"
objShtCut.Save
Set objShtCut = Nothing
End If
Next
Can't you use [Environment]::GetFolderPath("Desktop") to get the desktop's path for current user?