AutomationFocusChangedEventHandler: event dose not triggerd in powershell - powershell

I'm traying to detect focus change using a powershell script, hier is my code
start calc
Write-Host "Loading MS UIA assemblies"
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClient")
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationTypes")
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationProvider")
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClientsideProviders")
try
{
# WORKAROUND: There is a weird bug: first call fails ...
[Windows.Automation.ClientSettings]::RegisterClientSideProviderAssembly([UIAutomationClientsideProviders.UIAutomationClientSideProviders].Assembly.GetName())
}
catch {}
# ... second call succeeds:
[Windows.Automation.ClientSettings]::RegisterClientSideProviderAssembly([UIAutomationClientsideProviders.UIAutomationClientSideProviders].Assembly.GetName())
$focusedElem = [Windows.Automation.AutomationElement]::FocusedElement #this one work fine
Write-Host "name: " $focusedElem.Current.Name
Write-Host "ControlType: " $focusedElem.Current.ControlType
Write-Host "ProcessId: " $focusedElem.Current.ProcessId
$onFocusChange = { # this dose not fired !!!!
param([Sytem.Object]$src, [Windows.Automation.AutomationFocusChangedEventArgs]$e)
start notepad
}
$focusChangeHandler = [Windows.Automation.AutomationFocusChangedEventHandler]($onFocusChange)
[Windows.Automation.Automation]::AddAutomationFocusChangedEventHandler($focusChangeHandler)
Start-Sleep -Seconds 5 #durring this sleep i change the focused window, but nothing happen :(
[Windows.Automation.Automation]:: RemoveAutomationFocusChangedEventHandler($focusChangeHandler)
any idea why this script not working, or any idea how to monitoring focus change in powershell without external tools ?

Related

Timeout an MS Access ComObject from powershell

I have a powershell script that creates an MS Access ComObject and uses it to run a macro in an MS Access database as shown below:
$AccessDb= New-Object -ComObject Access.Application
try{
foreach($file in $Files)
{
...
$AccessDb.DoCmd.RunMacro('mcrScr')
...
}
}
catch { ... }
The issue is when there are runtime errors, MS Access throws the errors in an interactive window or dialog box and this causes the powershell to hang; just waiting for the window to close and thus macros for other .mdb files do not get to run.
I have been trying out options from online articles to timeout this piece of my code $AccessDb.DoCmd.RunMacro('mcrScr'), if it runs more than x number of seconds. I used jobs, runspace and [system.diagnostics.stopwatch] but have not been successful.
Is there any better approach to do this. I am kind of running out of options.
Edit:
#Paul, in response to your comment I am adding how i am using runspace to address the problem.
function Script-Timeout {
param([scriptblock]$Command,[int]$Timeout)
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.Open()
$PS = [powershell]::Create().AddScript($Command)
$PS.Runspace = $Runspace
$chk = $PS.BeginInvoke()
if($chk.AsyncWaitHandle.WaitOne($Timeout))
{
$PS.EndInvoke($chk)
}
else
{
throw "Command taking too long to run. Timeout exceeded."
$PS.EndInvoke($chk)
}
}
The Script-Timeout function is then used in the portion of my script that runs the MS Acess macro as shown below:
Try{
forEach($mdbfile in Files)
{
...
Script-Timeout -Command {
$AccessDb= New-Object -ComObject Access.Application
$AccessDb.OpenCurrentDatabase($mdbfile)
$AccessDb.DoCmd.RunMacro('mcrUpdate')
$AccessDb.CloseCurrentDatabase()
} -Timeout 20
...
}
}
catch
{
#catch exception
}
I have artificially created a runtime error in the VBA which throws an error dialog box. This way the RunMacro portion of the script, if it gets run, will hung the powershell. This is where i expect the runspace to timeout the macro run from powershell after x seconds.
The problem with runspace is that the MS Access Macro does not get run at all. In powershell debug mode, i see the if-block of the script-timeout function always execute successfully with or without the artificial runtime error

Run process using CMD command fails if the argument is not hardcoded

I want to run cmd command and run process:
This function works fins:
function RunProcess($processPath)
{
&$processPath "my argument"
}
Usage:
RunProcess "myExe.exe"
Now if I want to make it more generic and send also the argument:
function RunProcess($processPath, $ar)
{
&$processPath $ar
}
Usage:
RunProcess "myExe.exe" "my argument"
This failed and I don't know why.
Your code is working for me, you could try this as well:
function RunProcess($processPath, $ar)
{
Start-Process $processPath -ArgumentList $ar
}

How do I retrieve PR_RULE_ACTIONS via PowerShell and the EWS Managed API?

I have need of retrieving and inspecting the delegate forwarding rule (the built-in delegate commands in EWS being inadequate for my needs since they choke on groups being used as delegates).
I am able to successfully locate the rule created by "Schedule+ EMS Interface". However, I am unable to retrieve PR_RULE_ACTIONS. Turning on tracing.
I see that the PidTagRuleMsgProvider property is getting returned just fine, but PR_RULE_ACTIONS never does.
I suspect that I am using the wrong MAPI property type in the propertyset definition, but I've gone through everything listed at http://msdn.microsoft.com/en-us/library/exchangewebservices.mapipropertytypetype(v=exchg.140).aspx . Any clues?
Here is the relevant snippet of code:
# Setup Basic EWS Properties for Message Search - Used to locate Hidden Forwarding Rule
$searchFilterForwardRule = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, "IPM.Rule", [Microsoft.Exchange.WebServices.Data.ContainmentMode]::Prefixed, [Microsoft.Exchange.WebServices.Data.ComparisonMode]::Exact)
$itemViewForwardRule = New-Object Microsoft.Exchange.WebServices.Data.ItemView(30, 0, [Microsoft.Exchange.Webservices.Data.OffsetBasePoint]::Beginning)
$itemViewForwardRule.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties, [Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, [Microsoft.Exchange.WebServices.Data.ItemSchema]::Subject)
$itemViewForwardRule.Traversal = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Associated
# Properties for Hidden Delegate Forwarding Rule
$PID_TAG_RULE_MSG_PROVIDER = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65EB,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
$PID_TAG_RULE_ACTIONS = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x6680,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)
# Property Set for Delegate Forward Rule
$propertySetForwardRule = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties, $PID_TAG_RULE_MSG_PROVIDER)
$forwardRuleExists = $false
$findResults = $service.FindItems([Microsoft.Exchange.Webservices.Data.WellKnownFolderName]::Inbox, $searchFilterForwardRule, $itemViewForwardRule)
If ($findResults.TotalCount -lt 1) {
Write-Error "Failed to find rule" "Error"
} Else {
Foreach ($item in $findResults.Items) {
$item.Load($propertySetForwardRule)
If ($item.ExtendedProperties.Count -ge 1) {
If ($item.ExtendedProperties[0].Value -eq "Schedule+ EMS Interface") {
$forwardRuleExists = $true
write-host "Delegate forwarding rule found." -ForegroundColor Cyan
$propertySetForwardRule.Add($PID_TAG_RULE_ACTIONS)
$item.Load($propertySetForwardRule)
Write-Host "Attempting to retrieve x6680 PR_RULE_ACTIONS (PidTagRuleActions)" -ForegroundColor Cyan
$PR_RULE_ACTIONS = $null
if($Item.TryGetProperty($Pid_Tag_Rule_Actions,[ref]$PR_RULE_ACTIONS)){
return $PR_RULE_ACTIONS
} # endif
else {write-host "TryGetProperty for PR_RULE_ACTIONS failed!" -ForegroundColor Red
} # endelse
} # End If - Correct Message
} # End If - Has Extended Properties
} # End ForEach
} # End If - Message Count
Glen Scales was able to set me on the right path. It turns out that PR_RULE_ACTIONS is not exposed via EWS, but the same data exposed via an attribute called PR_EXTENDED_RULE_ACTIONS. Now I'm happily slinging code to parse the binary blob.
http://msdn.microsoft.com/en-us/library/ee218391(v=EXCHG.80).aspx
The property tag for PR_RULE_ACTIONS is 0x668000FE. You can see it (and the property data) in OutlookSpy (I am its author) - go to the Inbox folder, click IMAPIFolder button, go to the PR_RULES_TABLE tab, select the rule, double click on the PR_RULE_ACTIONS property.
Note that PT_ACTIONS MAPI type (0x000FE) is only accessing in Extended MAPI, I don't think EWS will be able to return it.

Hash entry sometime is $NULL (error), and sometimes isn't?

I have my little 3-sided socket-server. Each server has its own hash with its key-values.
The very first is:
$Local = #{ID="Local"; ...}
$RemtA = #{ID="RemtA"; ...}
$RemtB = #{ID="RemtB"; ...}
I start for all of the the listeners - no problem.
If now a client wants to connect, I want to add the ID to $ProgressHead, which is defined like this:
$ProgressHead = "Value-Broadcast, Connected: "
and used in my function to accept a client called with its hash as $h:
if ( !$h.Connected ) {
#Write-Host "$($h.ID) not connected, pending: $($h.listener.Pending())"
if ( $h.listener.Pending()) {
$h.client = $h.listener.AcceptTcpClient() # will block here until connection
$h.stream = $h.client.GetStream();
$h.writer = New-Object System.IO.StreamWriter $h.stream
$h.writer.AutoFlush = $true
$h.Connected = $true
Write-Host $Global:ProgressHead # fails - empty ??
Write-Host $h.ID # prints oh depit it is marked as error
if ( !$Global:ProgressHead.Contains( $h.ID ) ) { # <= HERE IS THE ERROR ????
$Global:ProgressHead= "$($Global:ProgressHead)$($h.ID) "
}
}
}
The Error message says:
Can't call a method for an expression which is NULL and $h.ID is underlined
BUT I DO NOT get any error if I start this either in the cmd-console when running powershell -file ThreeServer.ps1 or within the ISE in debug mode. The ID is written correctly to $ProgressHead!
Only if I start this in the Powershell console (PS C:\...> ./ThreeServer.ps1) I get this error, but all the other keys in the lines above are valid ONLY $h.ID on ONLY the PS-console throws this error?

how do i prevent my script for waitnig for user input

i am writing a code that runs on remote computer using psexec, in some point of the code it stop and wait for user to press enter in order to continue , this only happens on remote! when i use local its fine, how do i prevent that and keep my code "rolling"?
code:
param(
[Parameter(ParameterSetName='database')] [string]$database,
[Parameter(ParameterSetName='file')] [string]$file,
[Parameter(ParameterSetName='server')] [string]$server,
[Parameter(ParameterSetName='mailbox')] [string]$mailbox,
[Parameter(ParameterSetName='all')] [switch]$all,
[string]$filename
)
if($mailbox) { $mailboxes = #(Get-Mailbox $mailbox) } ----->#it stop after this function#