将数组输出到Excel

时间:2018-12-31 19:06:59

标签: arrays excel powershell

我在办公室使用一个相当旧的脚本来分配电子传真号码时遇到了问题。它的所有者当然早已不复存在。我已经修复了脚本的基本使用问题,但是我试图简化它。我要解决的当前问题是它如何检查未使用的号码。

我认为当前版本的电话号码范围在文本文件中列出,例如“ 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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

  

我正在寻找一种将电话号码数组(总共约4k)拉入电子表格的方法

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

$AllFaxNumbers

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

Lengtharray。这是一个简单的传真号码列表,并且具有一个属性-TMwithFaxs-可以告诉您其中有多少个传真号码。

Displayname有点复杂;它是一个Microsoft.ActiveDirectory.Management.ADUser对象*,仅抽出Faxipmo 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 ,所有其他AD信息均被丢弃。

这很可能无法为您解决所有问题-最好将您的问题分解成碎片,并在发布问题时询问特定问题。

PSObject

* 因为您已经选择了所有可用属性的子集,所以它可能只是通用的notifyActor ! Notify.Send(123)-我没有本地要测试的AD。

答案 2 :(得分:0)

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

此方法可能有所不同,因为它创建了一个用于在Excel中导入的CSV文件,其中包含有关已使用和可用编号的信息。 生成的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