Powershell 2: размер массива отличается между возвращаемым значением и вызывающим - PullRequest
4 голосов
/ 07 сентября 2011

Я уже несколько часов бьюсь об этом, и Google не помогает.

У меня есть функция, которая вызывается в моем коде.Вызов выглядит так:

$newData = @(CreateMailContactIfNeeded $entry)

Вызываемая функция всегда должна возвращать массив из 2 элементов.Я подтверждаю это прямо перед оператором возврата вызванной функции:

# ... (inside CreateMailContactIfNeeded) ...
$tmpArr = @("$contactString" , "external")
Write-Host "length is" $tmpArr.length
Write-Host "Contact string is ->"$contactString"<-"
return $tmpArr

Длина всегда равна 2, а строка контакта всегда не равна нулю.Пример вывода:

length is 2
Contact string is -> GMSContact-33<-

(я не могу удалить начальный пробел в строке, поэтому я предполагаю, что это какой-то тип внутреннего форматирования строки powershell или что-то в этом роде)

ОДНАКО, когда яВернемся к вызывающей функции, иногда, но не всегда, массив, который я строю из возвращаемого значения, имеет длину three :

if ($newData.length -eq 3) {
  Write-Host "Weird - array length is 3..."
}

Write-Host "Array length now is "$newData.length
foreach ($tmpVar in $newData) {
  Write-Host "Array entry is "$tmpVar
}

Первый элемент массива из 3 записейявляется допустимой строкой, но это артефакт из более ранней обработки:

Weird - array length is 3...
Array length now is  3
Array entry is  Test User       <-- INVALID
Array entry is  GMSContact-33   <-- This should be first element
Array entry is  external        <-- This should be second element

Может кто-нибудь объяснить мне, что происходит и как это исправить?Я делаю присвоение массива неправильно?Учитывая приведенный выше код, как это возможно, что «тестовый пользователь» вставляется в массив?

EDIT: полное содержимое CreateMailContactIfNeeded ниже ...

function CreateMailContactIfNeeded {
  param($CSVEntry)

  $email = $CSVEntry.EMAIL_ADDR

  Write-Host    "--> Searching for $email"
  Write-Host -n "----> In AD? "
   # Return if this person already exists as a user in AD
  if (IsInOurADDomain $CSVentry) {
    Write-Host -f green "YES."
    Write-Host "Returning "$email "= inhouse"
    return @("$email" , "inhouse")
  } else {
    Write-Host -n -f gray "NO. "
  }

  $contactString = "GMSContact-" + $CSVEntry.MEMBER_ID
  Write-Host "Contact string is now " $contactString

  # Check if mail contact already exists. If not, create it.
  Write-Host -n "In Contacts? "
  $object = Get-MailContact $email 2> $null

  if ($object -eq $null) {
    $displayName = $CSVentry.FIRST_NAME + " " + $CSVentry.LAST_NAME

    Write-Host -n -f gray "NO. "
    Write-Host -n "Creating contact... "

    $error.clear()
    New-MailContact -Name $contactString                    `
                    -DisplayName $displayName               `
                    -ExternalEmailAddress $email            `
                    -OrganizationalUnit $global:OU_CONTACT_STRING  
    if ($error[0] -ne $null) {
      Write-Host -f red "ERROR"
      Write-Error $error[0]
      return @("error","error")
    }
    # Derek says to do this to make it appear in alternate address book
    Set-MailContact -identity $contactString -customattribute1 "AB2"
    Write-Host -f green "SUCCESSFUL"
  } else {
    Write-Host -f green "YES"
  }
  Write-Host "Returning" $contactString "= external"
  $tmpArr = @("$contactString" , "external")
  Write-Host "length is" $tmpArr.length
  Write-Host "Contact string is ->"$contactString"<-"
  Write-Host "Contact string length is "$contactString.length
   foreach ($tmp in $tmpArr) {
     Write-Host "In function element is "$tmp
   }
   return $tmpArr
#  return @("$contactString" , "external")
}

Ответы [ 2 ]

6 голосов
/ 07 сентября 2011

В Poweshell все, что не «захвачено», фактически «возвращается».

Давайте рассмотрим пример:

function test(){

    "starting processing"

    #do some processing

    write-host "starting different process"
    $output = @("first",second")
    return $output
}

Когда вы сделаете что-то вроде $myoutput =test, вы увидите, что $ myoutput на самом деле имеет три элемента - first,second, как и ожидалось, а также starting processing. Потому что starting processing был не захвачен и "возвращен" в конвейер.

Везде, где в вашем скрипте генерируется неверный вывод "TEST USER", попробуйте захватить вывод или направить его на Out-Null или назначить на $null


Простой способ выяснить, откуда дополнительный элемент "возвращается".

Измените сценарий, чтобы не записывать выходные данные функции в переменную. Так что оставьте это как CreateMailContactIfNeeded $entry

Перед запуском скрипта запустите Set-PsDebug -trace 1. Теперь запустите скрипт - вы сможете увидеть, куда возвращается TEST USER. Захватите его, как указано выше.

2 голосов
/ 07 сентября 2011

Помните, что return $something в PowerShell - это просто способ сказать

$something
return

То есть все, что выпадает из функции, является частью возвращаемого значения; return просто выпрыгивает из функции.

Так что я предполагаю, что где-то перед вашим возвратом значение "Test User" выпадает из конвейера. Write-Host и задания никогда не вернут ничего, но New-MailContact может быть. Или Set-MailContact. Это единственные две строки, которые могут вернуть все, что может непреднамеренно вернуть что-либо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...