2016-07-08 4 views
1

Следующая часть кода должна пересекать один массив «idleusers», удаляя этих пользователей из «конечных пользователей» из массива, если у них также есть определенное приложение.Удаление из ArrayList не работает

$apps = get-process -IncludeUserName | Sort-Object -Property ID -Unique 

foreach ($app in $apps){ 
    if ($idleusers -contains $app.username) { 
     if ($app.path -like 'C:\Program Files (x86)\DirectoryOfTheApplication\*') { 
      #if ($app.username -eq 'Domain\UsernameThatDoesNotRemove') { 
      # $finalusers.remove('Domain\UsernameThatDoesNotRemove') 
      #} 
      $finalusers.remove($app.username) 
     } 
    } 
} 

$finalusers 

Это работает, и удаляет большинство нужных пользователей, но есть 2 или 3 пользователей осталось, что не удаляются. Записанный цикл if - это тот, который я использовал, чтобы попробовать и отлаживать. Когда вы не комментируете эти строки и запускаете код, он удаляет пользователя. Это означает, что инструкции if должны работать должным образом, и проблема, скорее всего, выполняется с помощью инструкции remove.

Edit 2: Извините за плохой вопрос, я был Lurker здесь в течение длительного времени, но это мой первый выстрел на участие. Я прочитал статью справки и попытался сузить код. Вот он, полный скрипт, без функций и без чего-либо, что не относится к этой ошибке:

$quserresult = invoke-expression -Command "quser /SERVER:$serverName" | select -Skip 1  

$users = @() 

foreach($row in $quserresult) 
{   
    $person = new-object Object 
    $columns = $row.Replace(" ", " ").Split(" ") | ? {$_ -ne ""}  

    $person | add-member -membertype noteproperty -name UserName -value $columns[0]   

    $users += $person 
} 

$idleusers = @() 
foreach($usrn in $users){ 
    $nme = $usrn.UserName 
    $idleusers += "Domain\$nme"  
} 

[System.Collections.ArrayList]$finalusers = $idleusers 

$apps = get-process -IncludeUserName | Sort-Object -Property ID -Unique 

foreach ($app in $apps){ 
    if ($idleusers -contains $app.username) { 
     if ($app.path -like 'C:\Program Files (x86)\DirectoryOfTheApplication\*') { 
      #if ($app.username -eq 'Domain\UsernameThatDoesNotRemove') { 
      # $finalusers.remove('Domain\UsernameThatDoesNotRemove') 
      #} 
      $finalusers.remove($app.username) 
     } 
    } 
} 

$finalusers 

Final Edit: Спасибо, это было потому, что -contains не чувствительна к регистру. Я обязательно отформатировал его в нижнем регистре, и теперь он работает.

Окончательный код: комментарий

$quserresult = invoke-expression -Command "quser /SERVER:$serverName" | select -Skip 1  

$users = @() 

foreach($row in $quserresult) 
{   
    $person = new-object Object 
    $columns = $row.Replace(" ", " ").Split(" ") | ? {$_ -ne ""}  

    $person | add-member -membertype noteproperty -name UserName -value $columns[0]   

    $users += $person 
} 

$idleusers = @() 
foreach($usrn in $users){ 
    $nme = $usrn.UserName.ToLower() 
    $idleusers += "staley\$nme"  
} 

[System.Collections.ArrayList]$finalusers = $idleusers 

$apps = get-process -IncludeUserName | Sort-Object -Property ID -Unique 

foreach ($app in $apps){ 
    $appuser = $null 
    $appuser = $app.username 
    if ($appuser) { 
     if ($idleusers -contains $appuser.ToLower()) { 
      if ($app.path -like 'C:\Program Files (x86)\DirectoryOfTheApplication\*') { 
       $finalusers.remove($appuser.ToLower()) 
      } 
     } 
    } 
} 

$finalusers 
+2

Адрес электронной почты: Где остальная часть кода? Мы не можем рассказать вам, что происходит с переменной $ finalusers, потому что вы не указали, как она заселена. – pabrams

+0

По-прежнему трудно помочь. Это поможет вам прочитать статью «Как создать минимальный, полный и проверенный пример» в справочном центре. Если вы подозреваете, что проблема связана с ArrayList-> remove, попробуйте создать минимальный, полный и проверяемый пример. – pabrams

+1

Что касается msdn, ArrayList :: remove использует Object.Equals для поиска. Вы уверены, что ** $ app.username ** имеет тот же случай, что строки в ** $ finalusers ** –

ответ

0

Джонатана Мюллера почти наверняка указывает на вашу проблему.

Сравнение $idleusers -contains $app.username не так строго, как сравнение, используемое ArrayList, когда оно пытается удалить элемент $app.username. Первое сравнение будет соответствовать «Domain \ UserName» с «domain \ username», но последнее не будет. Если вы используете -ccontains вместо -contains, это будет чувствительно к регистру, но я не думаю, что это решит вашу проблему, это только сделает сравнение более последовательным - вполне вероятно, что изменение кода в get-terminal-users является правильным решением.

Однако я не могу воспроизвести проблему, потому что вы не разместили код для get-terminal-users.

+0

Спасибо за помощь и помощь Джонатана, это был правильный ответ. Я неправильно понял команду -contains и думал, что она чувствительна к регистру. –