Need help working with comaddins.connect - powershell

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.

Related

Powershell Startup Script GPO Not Applying

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.

PowerShell - showing a message on remote computer screen

When I am running commands or installing software remotely using PowerShell - Invoke-Command etc I would like sometimes to be able to show a message on the remote screen so the user knows something is happening, or when work done etc.
I would like to if possible make this message look as professional as possible, e.g. better than just a standard winform message box if it can be done? perhaps more the style of the Windows 10 ones with coloured background and use of image if possible.
Spent a while googling but most seem to relate to using obsolete methods such as net-send or using msg.exe.
Thanks
https://michlstechblog.info/blog/powershell-show-a-messagebox/
So the issue really isnt creating the messagebox itself, its having it show on the users session.
So when you run a command against a system, youre using your creds to run the command therefore it wont show in the users session. You can get around this by running it in the users context using a task scheduler. I have a script that does all this for you but, id hate to recreate the wheel and will have to wait till monday (when im at work) to post it here.
It accepts user input in your sessions that outputs it to a vbs, which then copies it over the message to the users machine, and a task schedule is set to run immediately for the user thats logged in.
edit: The script is this without the task scheduler. I just invoke gwmi win32_computersystem | Select -ExpandProperty username to get the current user logged in and add it to the task.
#Prompt for messge
$strMSG = Read-Host -Prompt "Enter message"
#deleting vbs if it exists
del C:\brief\test.vbs
#creating vbs from scratch so it doesnt override
New-Item C:\brief\test.vbs
#Appending each the values to a seperate line
Add-Content C:\brief\test.vbs 'Set objShell = Wscript.CreateObject("WScript.Shell")'
Add-Content C:\brief\test.vbs "strText = `"$strMSG`""
Add-Content C:\brief\test.vbs 'intButton = objShell.Popup(strText,0,"Computer Support",48)'
#calling on the script
& cscript C:\brief\test.vbs
Found a great solution here which appears on quick testing to work well for displaying a toast notification on a remote machine
https://smsagent.blog/2019/06/11/just-for-fun-send-a-remote-toast-notification/

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

How do I run Invoke-WebRequest cmdlet from third party program?

I have been trying to get this to work via a game control panel TCAdmin.
$ModPg1 = Invoke-WebRequest "http://steamcommunity.com/sharedfiles/filedetails/?id=731604991"
$ModVer1 = ($ModPg1.ParsedHtml.getElementsByTagName('div') | Where{ $_.className -eq 'detailsStatRight' } ).innerText | Select -Last 1
If I run this cmdlet via a program like TCAdmin (or task scheduler), I get the following error....
Invoke-WebRequest : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.
Explorer is installed, and set up. The script works just fine if I run it manually.
My guess is there is a way to get TCAdmin to run the scripts the same way I would as a windows User.
Cant find a way nearly as simple to scrape the info 'm looking for.
As for this...
get TCAdmin to run the scripts the same way I would as a windows User.
For any app to run as a user, that users profile must be used on the host where the code is to be run. You cannot natively run PoSH on a host as another user context. This is not a PoSH issue, it is a Windows User Principal security boundary. There are tools that let you do this. For example SysInternal PSExec and AutoIT. Yet as stated that error is pretty specific. The user profile for Internet Explorer has not been created and that only happens when you use IE at least once.
So, as Adam points, out, use the setting the error message states to use or use your code to start IE at least once.
$SomeUrl = 'https://stackoverflow.com'
$ie = New-Object -com internetexplorer.application
$ie.visible = $true
$ie.navigate($SomeUrl)
while ($ie.Busy -eq $true) { Start-Sleep -Seconds 1 } # Wait for IE to settle.
Again, if trying to run this in the context of another user, the two above tools will get you there, but you still have to fire up IE to have a profile for it.

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.