How to modify COM+ applications from powershell - powershell

I am automating the creation of a web server. An application is created for me, but I need to manually change the Identity of a COM+ Application to run as a specific user.
Being a linux admin with little experience with powershell, I'm in over my head. It looks like there is an API to modify COM+ applications.
https://msdn.microsoft.com/en-us/library/ms679173(v=vs.85).aspx
From this stackoverflow question, I've gotten this far in modifying the application
$comAdmin = New-Object -comobject COMAdmin.COMAdminCatalog
$apps = $comAdmin.GetCollection(“Applications”)
$apps.Populate();
I am able to see my application in the list by typing in this command
$apps
Is it possible to modify the foobar application Identity from powershell?

Thanks to this stackoverflow question, I got it working.
$targetApp = "examplecompany"
$comAdmin = New-Object -comobject COMAdmin.COMAdminCatalog
$apps = $comAdmin.GetCollection("Applications")
$apps.Populate();
$app = $apps | Where-Object {$_.Name -eq $targetApp}
$comAdmin.ShutdownApplication($targetApp)
$app.Value("Identity") = 'example.com\exampleuser'
$app.Value("Password") = 'correct-horse-battery-staple'
$apps.SaveChanges()
$comAdmin.StartApplication($targetApp)

Related

Creating a RDP icon on desktop with specific parameters

Does anybody have a Powershell script that generates a RDP icon on the desktop of the user. I already have the code for the desktop icon creation. But the next thing I need is the RDP extension to be created with specific paramters (Single usage of monitor)
Thanks in advance!
$wshshell = New-Object -ComObject WScript.Shell
$lnk = $wshshell.CreateShortcut("C:\Users\Public\Desktop\RDP.lnk")
$lnk.TargetPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\Remote Desktop Connection.lnk"
$lnk.Description = "RDP"
$lnk.Save()
You did it almost correct. But better to set TargetPath to mstsc.exe directly.
Use $lnk.Arguments to set parameters like server name (/v), fullscreen (/f) and others.
$wshshell = New-Object -ComObject WScript.Shell
$lnk = $wshshell.CreateShortcut("C:\Users\Public\Desktop\RDP.lnk")
$lnk.TargetPath = "%windir%\system32\mstsc.exe"
$lnk.Description = "RDP"
$lnk.Arguments = "/v:server-1 /f"
$lnk.Save()
If you need some tweaks inside mstsc its better to use shared folder for all computers and place .rdp file with your config here. After that use $lnk.TargetPath to this .rdp file.

New-Object -ComObject -Servername

I wanted to know in PowerShell if there is a way New-Object -ComObject can be run against a remote server like how it's possible natively in VBScript WScript.CreateObject("COM Server", "RemoteServerName").
If not, is there an option without having to rely on PS Remoting technologies?
I don't think it's possible to instantiate remote COM objects via New-Object. You should be able to get the desired result via the GetTypeFromProgID() and CreateInstance() methods, though:
$server = 'RemoteServerName'
$type = [Type]::GetTypeFromProgID('COM Server', $server, $true)
if ($type) {
$obj = [Activator]::CreateInstance($type)
}
[source]

Using IE automation in powershell to login to a website that has input validation

I am trying to use PowerShell to login to a website. In the example below I am trying to login to live.com.
I am able to update the username field but the webpage runs some sort of input validation that does not accept my value. If I manually go in and edit the username field, like hitting space and then backspace, the input is then valid.
I found some documentation about changing the focus or using fireevent, but neither seems to work.
While sendkeys would resolve my issue, I have had numerous problems with sendkeys before and would really like to avoid going down that path.
$Site = 'https://login.live.com'
$UserName = 'FakeUserName#outlook.com'
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Visible= $true
$ie.Navigate($Site)
while ($IE.busy)
{
Start-Sleep -Milliseconds 100
}
$Inputs = $IE.document.getElementsByTagName("input")
foreach ($Input in $Inputs)
{
if ($Input.type -eq "email")
{
$UserIDField = $Input
}
if ($Input.type -eq "submit")
{
$LoginButton = $Input
}
}
$UserIDField.focus()
$UserIDField.value = $UserName
$UserIDField.FireEvent('onchange')
$LoginButton.focus()
$LoginButton.click()
#Ranadip Dutta is certainly true, you should not, do that this way, but if you want to automate web browser Selenium is a good tool, here it tooks five minutes to automate Chrome on your web site. You can chooe an IE driver,Mozilla or Opera. for that have a look to Selenium.
# Selenium directory is the place where I expand Selenium Client & WebDriver Language Bindings for C#
$seleniumDir = 'D:\Developpements\Pgdvlp_PowerShell\selenium-dotnet-3.0.0'
# Selenium Webdriver
Add-Type -Path "$seleniumDir\net40\WebDriver.dll"
Add-Type -Path "$seleniumDir\net40\WebDriver.Support.dll"
Add-Type -Path "$seleniumDir\net40\ThoughtWorks.Selenium.Core.dll"
Add-Type -Path "$seleniumDir\net40\Selenium.WebDriverBackedSelenium.dll"
# With Chrome
# I Download Chrome driver here : https://chromedriver.storage.googleapis.com/index.html?path=2.25/
# It stands in "$seleniumDir" drive
$chrome = New-Object OpenQA.Selenium.Chrome.ChromeDriver "$seleniumDir"
#$chrome.Navigate().GoToUrl("https://fr.hightail.com/loginSpaces?redirect_url=https%3A%2F%2Fspaces.hightail.com%2Foauth%2Fhightail");
$chrome.Navigate().GoToUrl("https://login.live.com");
$Browser = $chrome
$email = $Browser.FindElements([OpenQA.Selenium.By]::Name('loginfmt'))
$email[0].SendKeys("adress#hotmail.com")
$button = $Browser.FindElements([OpenQA.Selenium.By]::Id('idSIButton9'))
$button.Click()
Start-Sleep 2
$passwd = $Browser.FindElements([OpenQA.Selenium.By]::Name('passwd'))
$passwd[0].SendKeys("toto")
$button = $Browser.FindElements([OpenQA.Selenium.By]::Id('idSIButton9'))
$button.Click()
If your website is checking for automated login then how can you expect it to be automated in this way. Sendkeys actually send like user input which is similar to what user does and thereby sorts your problem in that case.
I would like you to see if there is any API available for the web service to get logged in.
Other than that, I do not see anything which can help you. This concern is not about powershell or any scripting language. It is pretty much generic for your website.
You may also want to consider passing stored credentials more securely instead of putting your creds in full view plain text within your script(s).
TechNet - PowerShell Tip - Storing and Using Password Credentials

How to create a com object in another domain?

I'm trying to use PowerShell to quickly find the Scheduled Tasks in the root folder of a remote server. I find all sorts of scripts that others have written, but they're either looking at the localhost or on a server in the same domain. I support servers in dozens of domains, so I need some way to pass along credentials.
Here's the meat of my script:
$server = "<computername>"
$schedule = new-object -com("Schedule.Service")
$Schedule.connect($server)
$folder = $schedule.GetFolder("")
$tasks = $folder.GetTasks("")
foreach($task in $tasks) {
if (($task = $Folder.GetTasks(0))) {
$Tasks| ForEach-Object {[array]$results += $_}
$Tasks | Foreach-Object {
New-Object -TypeName PSCustomObject -Property #{
'Name' = $_.name
<etc.>
<etc.>
}
}
}
That code works fine either on my localhost or a server in the same domain as my workstation. In other scripts, I use Get-Credential to create $creds and (in various ways) pass that to the appropriate cmdlet. But with this one, I'm not sure. 'New-Object' doesn't accept a -Credential parameter. I've tried wrapping various parts inside an Invoke-Command scriptblock, since that accepts -Credential, but it fails in various ways. I'm not sure what needs to be wrapped in Invoke-Command--just the new-object? The foreach loop? The entire thing?
Thanks in advance.
When doing the Connect call, you can pass the server, domain, username, and password:
$Schedule.Connect($serverName, $user, $domain, $password);
This should allow you to use that object on the new domain.
MSDN Reference

COMAdmin - force refresh of applications after install of proxy

I'm programmatically installing a COM+ proxy component via Powershell, using msiexec on the msi, and then using the COMAdmin.COMAdminCatalog object to set the remote server on the proxy.
The problem is that it takes a while for the newly installed proxy to be available in the "Applications" collection of COMAdminCatalog. Is there some way to force a refresh of the catalog before getting the application list?
Essentially, what I do is this:
msiexec /q /i $appName.msi
use the COMAdmin.COMAdminCatalog to enumerate the apps.
function Set-Remote-Server-For-Complus-Application($appName, $remoteServer) {
$comAdmin = New-Object -comobject COMAdmin.COMAdminCatalog
$apps = $comAdmin.GetCollection("Applications")
$apps.Populate();
$app = $apps | Where-Object {$_.Name -eq $appName}
if ($app -eq $null) {
Write-Warning "Unable to find COM+ app ""$appName""."
Return
}
$app.Value("ApplicationProxyServerName") = $remoteServer
$result = $apps.SaveChanges()
$apps = $null
if ($result -eq 1) {
Write-Output "Successfully set complus remote server ""$remoteServer"" on ""$appName"""
}
}
The problem is that the application is not Found. If I add a Start-Sleep -Seconds 2 between the calls, it works. But, sleeping is not good, because sometimes it might take longer than 2 seconds, sometimes it might only take 200 milliseconds, so the wait is unnecessarily long.
Is there any way to make sure that the COMAdmin.COMAdminCatalog is actually updated before I try to enuerate the applications, without resorting to sleeping and just hoping for the best?