# Trigger uninstall of an MSI file
$computername="SERVER007"
$keywordSearch="Polycom*"
$installFile="\\FILESHERVER\Software\Polycom\Polycom_BToE_Connector_4.0.0.0 (new for 2019-07-19)\Polycom_BToE_Connector_4.0.0.0.msi"

# Trigger silent install of an MSI file
function installApp($installFile){
msiexec.exe /i $installFile /qn /norestart
"Install has been triggered. Waiting 30 seconds for app listing..."
Sleep 30;
get-wmiobject Win32_Product | Select IdentifyingNumber, Name
}

# Trigger silent uninstall of an MSI file
function uninstallApp ($appNameKeyword){
#$productGUID=(get-wmiobject Win32_Product -ComputerName $computerTarget | Where-Object {$_.Name -like $appNameKeyword}).IdentifyingNumber;
$productGUID=(get-wmiobject Win32_Product | Where-Object {$_.Name -like $appNameKeyword}).IdentifyingNumber;
if ($productID){
msiexec.exe /x $productGUID /qn;
}
else{
"Application with keyword $appNameKeyword not found."
# Check for exising installs
#get-wmiobject Win32_Product -ComputerName $computername | Select IdentifyingNumber, Name
get-wmiobject Win32_Product | Select IdentifyingNumber, Name
}
}

function installOnRemote($server,$app){
Invoke-Command -computername $server -credential $cred -ScriptBlock {
param( $x, $importedFunc)
"Executing script on $($ENV:computername)..."
# Import the function from the variable inside parameters
[ScriptBlock]::Create($importedFunc).Invoke($x)
} -ArgumentList $app, ${function:installApp}
}

function uninstallOnRemote($server,$app){
Invoke-Command -computername $server -credential $cred -ScriptBlock {
param( $x, $importedFunc)
"Executing script on $($ENV:computername)..."
# Import the function from the variable inside parameters
[ScriptBlock]::Create($importedFunc).Invoke($x)
} -ArgumentList $app, ${function:uninstallApp}
}



# Check whether a given username matches the list of Domain Admins
function validateDomainAdmin{
param (
[string]$username
)
$matchedAdmin=$username -in $domainAdmins
if($matchedAdmin){
Write-Host "$username is a Domain Admin";
return $True;
}else{
Write-Host "$username not a Domain Admin.";
return $False;
}
}

function testCredential{
param (
[string]$username,
[string]$password
)
$plaintextPassword = (New-Object System.Management.Automation.PSCredential 'N/A',$providedPassword).GetNetworkCredential().Password
$domainBindTest = (New-Object System.DirectoryServices.DirectoryEntry($domainObject,$username,$plaintextPassword)).DistinguishedName
if ($domainBindTest){return $True;} else{Return $False;}
}

function obtainDomainAdminCred{
$domainAdmins=(Get-ADGroupMember -Identity "Domain Admins" -Recursive | %{Get-ADUser -Identity $_.distinguishedName} | Where-Object {$_.Enabled -eq $True}).SamAccountName
$global:cred=$False
do {
$providedID=Read-Host -Prompt 'Input a domain admin username'
if (validateDomainAdmin $providedID){
$providedPassword = Read-Host -assecurestring "Please enter the password"
#$providedPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
#$providedCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $providedID,$providedPassword
$goodCredential=testCredential -username $providedID -password $providedPassword
if($goodCredential){
"Domain Admin Credential validated!";
$global:cred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $providedID,$providedPassword;
#return $True;
}
else{
"Password doesn't match.";
$global:cred=$False;
#return $False;
}
}else{
"Try again..."
#return $False;
}
} until ($cred)
}

obtainDomainAdminCred;
installOnRemote $computername $installFile;
uninstallOnRemote $computername $keywordSearch;