locked
power shell script help RRS feed

  • Question

  •  


    I've written code on how to open IE which i thought was pretty cool but not quit what i need........

    CODE:::::::::::::::::::::::::::::::

    $ie = new-object -com internetExplorer.application
    $ie | Get-Member -MemberType method | out-File $File
    $ie

     

    this is what i got so far

     

    $ie = NewObject PSObject  $ie | AddMember type NoteProperty processname "processname" ID "id"
    $ie | AddMember type NoteProperty name  value
    $ie | AddMember type NoteProperty name  value
    WriteOutput $ie

    • Edited by onezaner Sunday, December 12, 2010 10:14 PM
    Saturday, December 11, 2010 4:26 PM

Answers

  • In order to get the counters you're looking for you should look at Get-Counter.  You can easily get whatever you want that you can normally get from perfmon.  I have been working on something similar.  I hate to post it because it's not quite at the point where I want it, but it might help you.  I use jobs to kick off the collection of all of the counters.  I also used a modified version of the technique described in my article here to get the PIDs for the additional iexplore tabs.  If you are not using IE 8 this may not work for you.

    I know you said you're new to PowerShell so I hope this isn't too much at once.  Just let me know if you have any questions about the code.  I expect to get to work on this over the next few weeks.  When completed I will publish a final version to poshcode and the scripting guys repository - along with a follow up article that talks about the techniques.  In the meantime you may be able to just add the additional counters you're looking for and change the sample interval to make it work for your reqs.

    # TODO:
    # Get-MSIE8Tabs needs to be published as a module to the module repository
    # Looping and flushing to either disk or database - should include a check for the registry at the beginning
    # Consider parameterizing counters and sampleinterval
    
    # The below is in seconds - url and title information for the process comes from the beginning of the sample
    $sampleinterval = 15
    
    $counters = @()
    #### The Asterisk will be replaced by iexplore_pid
    $counters += '\Process(*)\% Processor Time'
    $counters += '\Process(*)\IO Read Operations/sec'
    $counters += '\Process(*)\IO Write Operations/sec'
    $counters += '\Process(*)\Pool Nonpaged Bytes'
    
    
    function Get-MSIE8Tabs {
    <#
      .Notes
       NAME: Get-MSIE8Tabs
       AUTHOR: Tome Tanasovski
       Version: 1.0
       CREATED: 11/16/2010
       LASTEDIT: 
       11/16/2010 1.0
        Initial Release
    
      .Synopsis
       This cmdlet gets info about the tabs running in all iexplore.exe windows
       
      .Description
       Get-MSIE8Tabs returns a collection of objects that represent each tab. 
       It will return the PID, Title, HWND, url, and reference to the document object for each tab.
        
      .Inputs
       None
       
      .Outputs
       A PSOBject that represents an IE 8 tab. It contains the PID, Title, HWND, URL, and a reference to the document object for the tab.
       The document object is a reference. It will always contain live data. Title and URL is captured at the moment the object is created.
      
      .Example
       Get-MSIE8Tabs
    
      .LINK
       none
    
    #>
    
      $sig = @"
      [DllImport("user32.dll", SetLastError=true)]
      public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    
      [DllImport("user32.dll")]
      public static extern IntPtr GetTopWindow(IntPtr hWnd);
    
      [DllImport("user32.dll", SetLastError = true)]
      public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
    
      public enum GetWindow_Cmd : uint {
        GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_ENABLEDPOPUP = 6
      }
    
      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    
      [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
      public static extern int GetWindowTextLength(IntPtr hWnd);
    "@
      Add-Type -MemberDefinition $sig -Namespace MSIE8 -Name User32 -UsingNamespace System.Text
    
      $win = New-Object -comObject Shell.Application
      $windows = $win.Windows() |? {$_.locationurl} |% { New-Object psobject -Property @{url = $_.locationurl;Title = $_.document.title;Document=$_.document}}
    
      $iethreads = get-process iexplore |?{!$_.MainWindowTitle} |%{$_.ID}
    
      $p=0 #This will be the object that will hold the pid
      $window = [MSIE8.User32]::GetTopWindow(0)
    
      while ($window -ne 0) {
        [MSIE8.User32]::GetWindowThreadProcessId($window, [ref]$p) |out-null
        if ($iethreads -contains $p) {
          $length = [MSIE8.User32]::GetWindowTextLength($window)
          if ($length -gt 0) {
            $string = New-Object System.Text.Stringbuilder 1024
            [MSIE8.User32]::GetWindowText($window,$string,($length+1)) |out-null
            if ($string.tostring() -notmatch '^MSCTFIME UI$|^Default IME$|^SysFader$|^MCI command handling window$') {
              foreach ($w in $windows) {
                if ($string -match "^$($w.Title)") {
                  new-object psobject -Property @{PID = $p;Title = $string.tostring();HWND=$window;URL=$w.url;Document=$w.document}
                }
              }
            }
          }
        }
        $window = [MSIE8.User32]::GetWindow($window, 2)
      } 
    }
    
    $procs = Get-MSIE8Tabs
    
    # The below scriptblock is used by the PS jobs to get the counters
    $jobscript = {
      param(
        [Parameter(Mandatory=$true,Position=0)]
        [string] $counter,
        [Parameter(Mandatory=$true,Position=1)]
        [string] $interval,
        [Parameter(Mandatory=$true,Position=2)]
        [int] $procindex
      )  
      $sample = Get-Counter $counter -SampleInterval $interval    
      New-Object psobject -Property @{Counter=$counter;Value=$sample.CounterSamples[0].CookedValue;Time=$sample.TimeStamp;ProcIndex=$procindex}
    }
    
    if (Get-Job) {
      throw "There are existing PowerShell jobs running. This script requires the contents of Get-Job to return empty"
      break;
    }
    $i=0
    get-date
    foreach ($proc in $procs) {
      $proc |Add-Member -MemberType NoteProperty -Name date -Value (Get-Date)
      $proc |Add-Member -MemberType NoteProperty -Name SampleInterval -Value $sampleinterval
      foreach ($counter in $counters) {    
        $job = Start-Job $jobscript -ArgumentList @(($counter -replace '\*', "iexplore_$($proc.pid)"),$sampleinterval,$i)          
      }
      $i++
    }
    
    $jobs = Get-Job
    while ($jobs) {
      sleep 2
      Get-Job |receive-job
      $jobs = get-job |?{($_.State -ne "Completed") -and ($_.HasMoreData)}
      
    }
    Get-Job |Remove-Job
    
    $procs
    

     


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    • Marked as answer by IamMred Monday, December 13, 2010 11:36 AM
    Saturday, December 11, 2010 7:54 PM
  • Yeah, I'm sorry.  Like I said though - it really comes down to Get-Counter to do everything you are looking for:

    Get-Counter '\Process(*)\% Processor Time' -SampleInterval 15
    
    Get-Counter '\Process(iexplore)\% Processor Time' -SampleInterval 15
    

    The only problem is if you want to get multiple counters during the same sampling period you'll need to use jobs to do that with Get-counter

    The extra code in my script is all about associating the iexplore processes with the actual processes they are running.


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    • Marked as answer by IamMred Monday, December 13, 2010 11:36 AM
    Saturday, December 11, 2010 9:28 PM

All replies

  • In order to get the counters you're looking for you should look at Get-Counter.  You can easily get whatever you want that you can normally get from perfmon.  I have been working on something similar.  I hate to post it because it's not quite at the point where I want it, but it might help you.  I use jobs to kick off the collection of all of the counters.  I also used a modified version of the technique described in my article here to get the PIDs for the additional iexplore tabs.  If you are not using IE 8 this may not work for you.

    I know you said you're new to PowerShell so I hope this isn't too much at once.  Just let me know if you have any questions about the code.  I expect to get to work on this over the next few weeks.  When completed I will publish a final version to poshcode and the scripting guys repository - along with a follow up article that talks about the techniques.  In the meantime you may be able to just add the additional counters you're looking for and change the sample interval to make it work for your reqs.

    # TODO:
    # Get-MSIE8Tabs needs to be published as a module to the module repository
    # Looping and flushing to either disk or database - should include a check for the registry at the beginning
    # Consider parameterizing counters and sampleinterval
    
    # The below is in seconds - url and title information for the process comes from the beginning of the sample
    $sampleinterval = 15
    
    $counters = @()
    #### The Asterisk will be replaced by iexplore_pid
    $counters += '\Process(*)\% Processor Time'
    $counters += '\Process(*)\IO Read Operations/sec'
    $counters += '\Process(*)\IO Write Operations/sec'
    $counters += '\Process(*)\Pool Nonpaged Bytes'
    
    
    function Get-MSIE8Tabs {
    <#
      .Notes
       NAME: Get-MSIE8Tabs
       AUTHOR: Tome Tanasovski
       Version: 1.0
       CREATED: 11/16/2010
       LASTEDIT: 
       11/16/2010 1.0
        Initial Release
    
      .Synopsis
       This cmdlet gets info about the tabs running in all iexplore.exe windows
       
      .Description
       Get-MSIE8Tabs returns a collection of objects that represent each tab. 
       It will return the PID, Title, HWND, url, and reference to the document object for each tab.
        
      .Inputs
       None
       
      .Outputs
       A PSOBject that represents an IE 8 tab. It contains the PID, Title, HWND, URL, and a reference to the document object for the tab.
       The document object is a reference. It will always contain live data. Title and URL is captured at the moment the object is created.
      
      .Example
       Get-MSIE8Tabs
    
      .LINK
       none
    
    #>
    
      $sig = @"
      [DllImport("user32.dll", SetLastError=true)]
      public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    
      [DllImport("user32.dll")]
      public static extern IntPtr GetTopWindow(IntPtr hWnd);
    
      [DllImport("user32.dll", SetLastError = true)]
      public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
    
      public enum GetWindow_Cmd : uint {
        GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_ENABLEDPOPUP = 6
      }
    
      [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    
      [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
      public static extern int GetWindowTextLength(IntPtr hWnd);
    "@
      Add-Type -MemberDefinition $sig -Namespace MSIE8 -Name User32 -UsingNamespace System.Text
    
      $win = New-Object -comObject Shell.Application
      $windows = $win.Windows() |? {$_.locationurl} |% { New-Object psobject -Property @{url = $_.locationurl;Title = $_.document.title;Document=$_.document}}
    
      $iethreads = get-process iexplore |?{!$_.MainWindowTitle} |%{$_.ID}
    
      $p=0 #This will be the object that will hold the pid
      $window = [MSIE8.User32]::GetTopWindow(0)
    
      while ($window -ne 0) {
        [MSIE8.User32]::GetWindowThreadProcessId($window, [ref]$p) |out-null
        if ($iethreads -contains $p) {
          $length = [MSIE8.User32]::GetWindowTextLength($window)
          if ($length -gt 0) {
            $string = New-Object System.Text.Stringbuilder 1024
            [MSIE8.User32]::GetWindowText($window,$string,($length+1)) |out-null
            if ($string.tostring() -notmatch '^MSCTFIME UI$|^Default IME$|^SysFader$|^MCI command handling window$') {
              foreach ($w in $windows) {
                if ($string -match "^$($w.Title)") {
                  new-object psobject -Property @{PID = $p;Title = $string.tostring();HWND=$window;URL=$w.url;Document=$w.document}
                }
              }
            }
          }
        }
        $window = [MSIE8.User32]::GetWindow($window, 2)
      } 
    }
    
    $procs = Get-MSIE8Tabs
    
    # The below scriptblock is used by the PS jobs to get the counters
    $jobscript = {
      param(
        [Parameter(Mandatory=$true,Position=0)]
        [string] $counter,
        [Parameter(Mandatory=$true,Position=1)]
        [string] $interval,
        [Parameter(Mandatory=$true,Position=2)]
        [int] $procindex
      )  
      $sample = Get-Counter $counter -SampleInterval $interval    
      New-Object psobject -Property @{Counter=$counter;Value=$sample.CounterSamples[0].CookedValue;Time=$sample.TimeStamp;ProcIndex=$procindex}
    }
    
    if (Get-Job) {
      throw "There are existing PowerShell jobs running. This script requires the contents of Get-Job to return empty"
      break;
    }
    $i=0
    get-date
    foreach ($proc in $procs) {
      $proc |Add-Member -MemberType NoteProperty -Name date -Value (Get-Date)
      $proc |Add-Member -MemberType NoteProperty -Name SampleInterval -Value $sampleinterval
      foreach ($counter in $counters) {    
        $job = Start-Job $jobscript -ArgumentList @(($counter -replace '\*', "iexplore_$($proc.pid)"),$sampleinterval,$i)          
      }
      $i++
    }
    
    $jobs = Get-Job
    while ($jobs) {
      sleep 2
      Get-Job |receive-job
      $jobs = get-job |?{($_.State -ne "Completed") -and ($_.HasMoreData)}
      
    }
    Get-Job |Remove-Job
    
    $procs
    

     


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    • Marked as answer by IamMred Monday, December 13, 2010 11:36 AM
    Saturday, December 11, 2010 7:54 PM
  • wow that's some pretty hard core code there :)  IMO..

    the one one writting should be a little simpler then that  but i think i can pull some of what i need from it

    I appreciate it...

    Saturday, December 11, 2010 8:11 PM
  • Yeah, I'm sorry.  Like I said though - it really comes down to Get-Counter to do everything you are looking for:

    Get-Counter '\Process(*)\% Processor Time' -SampleInterval 15
    
    Get-Counter '\Process(iexplore)\% Processor Time' -SampleInterval 15
    

    The only problem is if you want to get multiple counters during the same sampling period you'll need to use jobs to do that with Get-counter

    The extra code in my script is all about associating the iexplore processes with the actual processes they are running.


    http://twitter.com/toenuff
    write-host ((0..56)|%{if (($_+1)%3 -eq 0){[char][int]("116111101110117102102064103109097105108046099111109"[($_-2)..$_] -join "")}}) -separator ""
    • Marked as answer by IamMred Monday, December 13, 2010 11:36 AM
    Saturday, December 11, 2010 9:28 PM