Powershell: Resizing windows by title, not by process id - powershell

I'd like to hear your input on this problem:
I have two Citrix Receiver/Workspace sessions active on my desktop and would like to resize the windows by their window title.
I'm aware of the solution to do this via the process id, e. g.
Get-Process | Where-Object { $.Name -eq 'CDVIEWER' -and
$.MainWindowTitle -like 'Window1' } | set-window -X 0 -y 0 -width
3850 -height 1150 -passthru
The problem is that all Citrix Workspace Client windows have the same process id. That leads to the consequence that I can resize only the Citrix Windows that was in the foreground as last.
Is there a way to set the window size by its title and not by its process id?
Thanks,
Thomas

You would need to use native functions imported from user32.dll to access the individual windows - i dont think you can do this from powershell alone. Checkout functions EnumChildWindows, GetWindowText and MoveWindow from above link - those are the building blocks of the functionality you require.
The process would be something like
Get the MainWindowHandle - eg [System.IntPtr] $WindowHandle =(get-process -Name notepad).MainWindowHandle (but for the citrix process).
Use EnumChildWindows with above Handle to locate all its child windows
Iterate through the child windows and use GetWindowText to find the required window (specifically its Handle). Only look at windows with Handles > 0 - there could be multiple other invalid or invisible windows listed.
Use MoveWindow to actually change the position of the window (using Window Handle above).
Id suggest you search each of the above and how to execute from powershell rather than trying to port the API calls to powershell yourself. Using these external functions can be a little tricky, but they are much more powerful.
If you write your own, always use try...catch...finally blocks to make sure you always clean up resources. Powershell cant do it for you with these functions. If you open it, close it, if you allocate memory, free it afterwards etc.
I dont have access to Citrix, but above functions should point you in the right direction.

Related

Powershell: Detecting that a specifically opened program is running (and closing it)

I'm trying to automate a workflow. The automation script is mainly written in Powershell It consists of these steps: 1) Opening a program 2) Communicating with the API, reading values, etc. 3) Closing the program. This script will be run many times a day, it would suffice to not close the program every time the script is finishing, but rather check at the beginning of the script whether the program is already opened, and if not, open it. I'd like to implement both, then decide which solution to use later on.
The code for opening the program is completed, but it's not enough to just run an .exe file to open the program, as I have to load the correct settings and GUI, for this while opening the .exe file from the command line, additionally, I have to use -s, also -c. I concluded all this in runProgram.cmd, so in the Powershell script, I only run this file to open the program. However, I am unsure how the already opened program can be detected (that it's opened), and how can I close it. I believe a solution might use processes, with the help of Get-Process, but I'm unsure of its capabilities and limitations (how do I check if my program's process is not amongst the list of running processes?), and whether there is a better way of dealing with this problem.
I have found the solution:
Open the program and open Powershell, and type Get-Process (this will list all the currently running processes)
Search yours (by name). If you don't know which process is the one you're looking for, you can close your program, then type Get-Process again, and look for the process that disappeared from the list, since you closed it. Let's assume the name of it is "yourprocess".
In the code, type $val = Get-Process -Name yourprocess. If it is running, $val should equal some data about the process, if it is not running, then $val is 0. Therefore, if you want to check whether it's opened, you should use:
if($null -ne $val){...}
Finally, stopping the process: Stop-Process -Name yourprocess.

Having Powershell Autofill command line prompt

There is an old command line tool my company uses to deploy log files to various servers.... whoever wrote it made it very very repetitive.
There is a lot of prompting that happens and I want to automate this process. We have a long term goal of replacing this .exe file down the line but for now automation works for the short term..
Example
./logdeploy.exe
Enter the destination folder:
I would like the powershell script to just automatically enter the folder, since its literally the same folder. because this exe is going to ask for it at least 20 times throughout this process, so copy paste just gets anyoing.
Is this even possible to do?
If there really is no way around simulating interactive user input in order to automate your external program, a solution is possible under the following assumption:
Your external program reads interactive responses from stdin (the standard input stream).
While doing so is typical, it's conceivable that a given program's security-sensitive prompts such as for passwords deliberately accept input from the terminal only, as so to expressly prevent automating responses.
If the first assumption holds, the specific method that must be used to send the response strings via stdin depends on whether the external program clears the keyboard buffer before each prompt.
(a) If it does not, you can simply send all strings in a single operation.
(b) If it does, you need to insert delays between sending the individual strings, so as to ensure that input is only sent when the external program is actively prompting for input.
This approach is inherently brittle, because in the absence of being able to detect when the external program is read to read a prompt response, you have to guess how much time needs to elapse between sending responses - and that time may vary based on many runtime conditions.
It's best to use longer delays for better reliability, which, however, results in increased runtime overall.
Implementation of (a):
As zett42 and Mathias R. Jessen suggest, use the following to send strings C:\foo and somepass 20 times to your external program's stdin stream:
('C:\foo', 'somepass') * 20 | ./logdeploy.exe
Again, this assumes that ./logdeploy.exe buffers keyboard input it receives before it puts up the next prompt.
Implementation of (b):
Note: The following works in PowerShell (Core) 7+ only, because only there is command output being sent to an external program properly streamed (sent line by line, as it becomes available); unfortunately, Windows PowerShell collects all output first.
# PowerShell 7+ only
# Adjust the Start-Sleep intervals as needed.
1..20 | ForEach-Object {
Start-Sleep 1
'C:\foo'
Start-Sleep 2
'somepass'
} | ./logdeploy.exe

Find named pipe associated with my IIS application

I have an IIS application with a named pipe binding. When I open powershell and run Get-ChildItem '\\.\pipe\', I see a long list of named pipes with crazy names like GUIDs. Some of them start with iisipm which I assume means they are created by IIS. How can I programmatically determine which one these pipes is associated with my IIS application?
A named pipe is just a file on the filesystem used for I/O through SMB. What you're asking is anlogous to saying, "I have a file on my desktop, what is using it?!" I will give you that your question is slightly more abstract because there are built-in ways to figure out read/writes to normal files via SACLs on Security Descriptors and using the Security event log. And while this can still be done with named pipes, you'd have to add a SACL to every named pipe and ensure proper auditing was turned on to catch this.
In this case, the easiest way to accomplish what you're looking for is to use Process Explorer to find all open handles to named pipes and find the IIS worker process that has a handle for it.
To do this:
Run Process Explorer, as admin
Press, CTRL-F for Find
Select, "File Handle or DLL..."
Type, "\Device\NamedPipe\"
..and identify which process is your IIS process and then which pipe it has a handle open to.
Edit: Handle.exe (also from Sysinternals) should also provide this information.

Need PowerShell help! Very strange things are happening

So I'm using PowerShell to manipulate a SharePoint 2010 library. I am uploading, downloading, and deleting files in a script using a custom module I made. My errors are so odd I can't understand them.I am using PowerGUI, Windows PowerShell ISE, and PowerShell Management Shell all in admin mode.
PowerGUI:
I sometimes can't get an spWeb object, sometimes I can. The URL string is being pulled from a CSV file so it never changes and neither does the code before I call Get-SPWeb -Identity $correctURL
Sometimes when I call a list RootFolder it returns $false for the Exists property, using management shell I can get past this. Otherwise I can touch it by calling $ListName.RootFolder.Files and it will magically return and hold the $true for Exists in future executions of my script.
Then when I call an XML file full of file properties(for uploaded files) it will return file property names for $fileFieldsXML.row.Attributes | foreach {$_} and values for $fileFieldsXML.row.Attributes | foreach {$_.ToString()}. This is, unless I set them to variables. When two very distinct vars are set to these two differentish calls they both are set to the array of property names! Why??
Windows PowerShell ISE and PowerShell Management Shell
I think these are just outdated somehow. I can call Get-SPWeb in Management Shell but I can't in ISE due to I guess outdated versions. Lately the management shell will act as if I haven't been doing anything to the files unless I close it out and reopen it. Does the management shell just hold a copy of all files when it starts or something? Can I make it update these files?
Can anyone suggest a better way to debug? Also why does a module seem to severely increase runtime? When everything was in the same script it was quick but my long functions take several times longer to execute now.
I also have been using PowerShell and SharePoint for almost two months now, so I am a beginner and intern. Perhaps that is really the cause of my problems :)

Is there a way to combine all powershell commands to remove win10 bloatware rather than doing it one by one?

I am trying to find a way to use Windows Powershell to remove Windows 10 bloatware (Get Skype, Money, Get Groove Music, etc. etc.)
all at once rather than typing each remove code separately. Is there a command for this or should I just suck it up and copy each command into powershell?
There is no ready-to-use command like this. But you can write a function or a module, containing them and then just call the function.
Have a look here, this is close to what you want.