【问题标题】:Outputting Array Into Excel将数组输出到 Excel
【发布时间】:2019-05-28 04:13:50
【问题描述】:

我对我们在办公室使用的用于分配 eFax 号码的相当旧的脚本提出了问题。它的主人当然早就不在了。我已经修复了脚本的基本使用问题,但我正在尝试简化它。我要解决的当前问题是它如何检查未使用的号码。

我已破译当前版本的电话号码范围列在文本文件中,例如“236,4000,4199”,然后它会遍历该范围并根据 Active Directory 中的每个用户配置文件检查每个号码,因此它的当然慢。因此,我正在研究的是一种将电话号码数组(总共约 4k)提取并输入电子表格的方法,然后我只需使用单独的脚本对 AD 进行检查以删除正在使用的电话号码。这样,它只需要引用一个文档,而不是针对几千个用户的几千个数字。

我还没有将它放入 Excel 中的任何内容,因为我还没有完全理解用于验证电话号码的数组,而且我不知道如何将每个号码输出到 Excel 中。这是读取数字的数组相关的原始代码:

ipmo act*
$FaxNUmbersINuse = @()
$AvailableFaxNumbers = @()
$AllFaxNumbers = @()

# - WFM Fax Numbers
$FaxNumberRange = Get-Content "\\CEWP9023\Share\FaxNumberRange.txt"

# - Get all Fax numbers 
Write-Host "Generating fax numbers..."

foreach ($FaxNumber in $FaxNumberRange) {
    $inparray = $FaxNumber.Split(',')
    $v1 = $inparray[0]
    $v2 = $inparray[1]
    $v3 = $inparray[2]
    $AllFaxNumbers += $v2..$v3 | foreach {"512-"+$v1+"-"+$_}
}

$FaxNumbersList = $null 
$FaxNumbersList = @{} 
$TMwithFaxs = Get-ADUser -Filter 'Fax -like "512-*"' -SearchBase "OU=REGIONS,DC=wfm,DC=pvt" -Properties * | select DisplayName, Fax
foreach ($TM in $TMwithFaxs) {
    $FaxNumbersList.Add($TM.DisplayName, $TM.Fax)
}

foreach ($AllFaxNumber in $AllFaxNumbers) {
    if ($FaxNumbersList.ContainsValue($AllFaxNumber)) {
        $FaxNUmbersINuse += $FaxNumbersList

【问题讨论】:

  • 查看您的代码是不完整的。 1) 一个foreach 循环,没有关闭}。 2)$_ 在这行$AllFaxNumbers += $v2..$v3 | foreach{"512-"+$v1+"-"+$_} 中来自哪里。 3) 不要使用-Properties *,如果您只需要显示名称和传真。
  • 结束语 } 在我从中获取的完整脚本中。不幸的是,这是一个 4 年前的脚本,我正在努力改进,所以我无法说出 $_ 的来源或使用它或 -Properties 的原因
  • @Theo $_ 是在管道之前指定的$v2..$v3 范围内的值。以@BGlast 为例,4000 到 4199。
  • @gms0ulman 谢谢,现在我明白了。我把它误认为是foreach ($var in $collection),而不是Foreach-Object。然后请忽略我的评论 2)

标签: arrays excel powershell


【解决方案1】:

如果您正在制作新的 CSV 文件(而不是修改现有文件),请考虑使用Export-CSV

【讨论】:

    【解决方案2】:

    我正在研究一种将电话号码数组(总共约 4k)提取并输入电子表格的方法

    您可以使用这些行导出生成的范围或 Active Directory 范围。我已将它们放入下面的脚本中,并对其进行注释以尝试解释数字是如何生成的。

    $AllFaxNumbers | Out-File "C:\temp\AllFaxNumber.txt"
    $TMwithFaxs | Export-Csv "C:\temp\ADFaxNumbers.csv" -NoType
    

    这是两种不同方法的原因在于对象的类型。

    $AllFaxNumbers 是一个array。这是一个简单的传真号码列表,只有一个属性 - Length - 告诉您其中有多少个传真号码。

    TMwithFaxs 有点复杂;这是一个Microsoft.ActiveDirectory.Management.ADUser 对象*,只有DisplaynameFax 被拉出,所有其他AD 信息都被丢弃。

    这很可能不会为您解决所有问题 - 最好将您的问题分解为多个部分,并在您发布问题时询问具体问题。

    ipmo act*
    $FaxNUmbersINuse = @()
    $AvailableFaxNumbers = @()
    $AllFaxNumbers = @()
    
    # - WFM Fax Numbers
    $FaxNumberRange = Get-Content "\\CEWP9023\Share\FaxNumberRange.txt"
    
    # - Get all Fax numbers 
    Write-Host "Generating fax numbers..."
    
    #using 236,4000,4199 as an example
    foreach ($FaxNumber in $FaxNumberRange) {
    
        $inparray = $FaxNumber.Split(',')       # split 236,4000,4199 into an array 
        $v1 = $inparray[0]                  # 236 is the first element
        $v2 = $inparray[1]                  # 4000 is the second element
        $v3 = $inparray[2]                  # 4199 is the third element
    
        # generate the numbers "512-236-4000" to "512-236-4199"
        # i.e. "512-236-4000", "512-236-4001", "512-236-4002" etc
        $AllFaxNumbers += $v2..$v3 | foreach {"512-"+$v1+"-"+$_}
    }
    
    $AllFaxNumbers | Out-File "C:\temp\AllFaxNumber.txt"
    
    $FaxNumbersList = $null 
    $FaxNumbersList = @{} 
    $TMwithFaxs = Get-ADUser -Filter 'Fax -like "512-*"' -SearchBase "OU=REGIONS,DC=wfm,DC=pvt" -Properties * | select DisplayName, Fax
    
    $TMwithFaxs | Export-Csv "C:\temp\ADFaxNumbers.csv" -NoType
    
    foreach ($TM in $TMwithFaxs) {
        $FaxNumbersList.Add($TM.DisplayName, $TM.Fax)
    }
    
    foreach ($AllFaxNumber in $AllFaxNumbers) {
        if ($FaxNumbersList.ContainsValue($AllFaxNumber)) {
            $FaxNUmbersINuse += $FaxNumbersList
    

    * 因为您选择了所有可用属性的子集,所以它可能只是一个通用的 PSObject - 我没有本地 AD 来测试。

    【讨论】:

    • 这也适用于阵列的其余部分,因此非常棒。我有另一位更精通的同事帮助我完成这个项目,这将有助于解决我们需要去哪里的障碍。
    【解决方案3】:

    如果我正确理解了这个问题,您有一个文本文件,您可以从中生成所有可能的传真号码的列表。 接下来,您要将其与 AD 中找到的数字进行比较,并使用该数字创建一个包含所有可用数字的新文件。

    这种方法可能有点不同,因为它创建了一个 CSV 文件,用于在 Excel 中导入,其中包含有关已使用数字和可用数字的信息。 生成的 CSV 文件将如下所示:

    "UserName","FaxNumber","Available"
    "Billy Joel","512-326-4000","No"
    "","512-326-4001","Yes"
    "Alice Cooper","512-326-4002","No"
    

    代码:

    Import-Module ActiveDirectory
    
    $path         = '\\CEWP9023\Share'
    $adSearchBase = 'OU=REGIONS,DC=wfm,DC=pvt'
    
    ##########################################################
    # Step 1: read the number ranges from the text file
    ##########################################################
    
    # - WFM Fax Numbers. Format: AreaCode, RangeStart, RangeEnd
    $faxNumberRange = Get-Content (Join-Path -Path $path -ChildPath 'FaxNumberRange.txt')
    
    # - Get all Fax possible numbers 
    Write-Host "Generating all possible fax numbers..."
    
    # use a HashSet object for faster lookup
    $generatedNumbers = New-Object 'System.Collections.Generic.HashSet[String]'
    foreach ($item in $faxNumberRange) {
        $areaCode, [int]$rangeStart, [int]$rangeEnd = $item -split ','
        # add the numbers unformatted for easier comparison later
        $rangeStart..$rangeEnd | ForEach-Object { 
            [void]$generatedNumbers.Add(("512{0}{1}" -f $areaCode, $_ ))
        }
    }
    
    
    ##########################################################
    # Step 2: find AD users with faxnumber
    ##########################################################
    
    # create a list containing PSCustomObjects storing user DisplayName 
    # and the faxnumber as it is entered in AD
    
    Write-Host "Retrieving all users with fax numbers..."
    
    # create a Hasttable for the info gathered from AD
    $userNumbers = @{}
    Get-ADUser -Filter 'Fax -like "512-*"' -SearchBase $adSearchBase -Properties DisplayName, Fax | 
        ForEach-Object {
            $fax = $_.Fax -replace '\D', ''   # remove all non-numeric characters
            if ($userNumbers.ContainsKey($fax)) {
                # Hmmmm. This number is already in the list. Possibly two or more users are found with the same number
                # Add this Nth user with a pipe symbol to the UserName property.
                $userNumbers.$fax.UserName += (' | {0}' -f $_.DisplayName)
            }
            else {
                $faxInfo = [PSCustomObject]@{
                    UserName  = $_.DisplayName
                    FaxNumber = $_.Fax
                    Available = 'No'
                }
                # use the unformatted faxnumber as Key
                $userNumbers.$fax = $faxInfo
            }
    }
    
    
    ##########################################################
    # Step 3: create a final list containing all numbers
    ##########################################################
    
    # Test each generated number against the (unformatted) AD faxnumbers
    # and add them in a new All-Numbers list
    
    Write-Host "Generating complete list of fax numbers and users..."
    
    # use an arraylist object for better performance
    $allNumbers = New-Object 'System.Collections.ArrayList'
    
    # loop through all generated numbers
    foreach ($fax in $generatedNumbers) {
        if ($userNumbers.ContainsKey($fax)) {
            # this is a number in use so add the info from AD
            [void]$allNumbers.Add($userNumbers.$fax)
        }
        else {
            # create a new entry for this unused number
            $faxInfo = [PSCustomObject]@{
                UserName  = ''                    # no user DisplayName also means: number is available
                FaxNumber = '{0}-{1}-{2}' -f $fax.Substring(0,3), $fax.Substring(3,3), $fax.Substring(6)
                Available = 'Yes'
            }
            [void]$allNumbers.Add($faxInfo)
        }
    }
    
    # you can free some memory here
    $generatedNumbers.Clear()
    $userNumbers.Clear()
    
    # output the completed list as CSV file
    $allNumbers.ToArray() | Export-Csv -Path (Join-Path -Path $path -ChildPath 'AllFaxNumbers.csv') -NoTypeInformation
    

    【讨论】:

      猜你喜欢
      • 2021-08-05
      • 2016-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 1970-01-01
      相关资源
      最近更新 更多