2017-12-14 20 views
0

Microsoft Access에서 테이블을 가져와 PowerShell 의 Import-CSV 테이블처럼 보이게하려고합니다. 여기서 CSV 파일의 각 열은 속성이됩니다. 및 행의 항목이 속성 값이됩니다.'Import-CSV'와 같은 Powershell 사용자 정의 객체를 만들 수있는 방법

$ColumnCount = 0; 
$contactObject = new-object PSObject; 
if ($rs.RecordCount -ne 0) { 
    do { 
     $rs.MoveFirst() 
     $valueArray = @(); 
     do { 
      foreach ($columnHeader in $rs.fields.item($ColumnCount).name) { 
       $value = $rs.Fields.Item($columnHeader).Value; 
       $valueArray += $value  
      } 
      $rs.MoveNext() 
     } until ($rs.EOF -eq $True) 
     $contactObject | Add-Member -MemberType NoteProperty -Name $columnHeader -Value $valueArray;  
     $ColumnCount++ 
    } until ($ColumnCount -eq $rs.fields.count) 
} 

그리고이 출력 : 내가 했어 유일한 가까운 성공은 이것이다

EquipmentPackageID  ElementID   ArchitectureID Delete       

------------------  ---------   -------------- ------       

{117, 117, 126, 126...} {32, 32, 32, 32...} {-1, 1, -1, 1...} {False, False, False, False...} 

하지만 개별 배열을 원하지 않는다.

기본적으로 모두 하나의 테이블이되고 싶습니다. 그리고이 함수는 다른 크기와 명명 된 테이블을 액세스 할 수 있어야합니다. 그래서이 4 열 테이블에 맞게 조정 된 사용자 지정 개체를 만들 수 없습니다.

또한
$MyFiles = Get-ChildItem C:\Windows\ | ForEach-Object { 
    [pscustomobject]@{ 
     Name = $_.Name; 
     FullName = $_.FullName; 
     CreationDate = $_.CreationTime.Date; 
    } 
} 

,이 패턴을 피하기 :

$Array = @() 
$x | ForEach-Object { 
    $Record = [...] 
    $Array += $Record 
} 

Basic .NET에서 배열의 크기를 조정할 수 없습니다

+1

코드를 밖으로 뒤집어 데이터베이스의 각 레코드에서 하나의 사용자 지정 개체를 만든 다음 배열에 사용자 지정 개체를 추가해보십시오. –

+0

나는 그걸 시도 해봤습니다. 각 값에 대해 add-member를 반복 한 다음 함께 추가하십시오.그리고 그것은 작동하기 시작한 것 같지만 ** 오류가 발생합니다 : "add-member : 이름이"Delete "인 멤버를 추가 할 수 없습니다. 그 이름을 가진 멤버가 이미 존재하기 때문에 멤버를 덮어 쓰려면 명령에 매개 변수를 강제하십시오. "** 그리고 만약 내가 추가하면 -force는 여전히 작동하지 않습니다. 그러나 첫 번째 기록을 위해 멋진 테이블을 출력합니다. – matt

답변

1

PowerShell을 버전 3.0 +의 기본 패턴은 다음과 같이한다. 즉, $Array += [...]은 완전히 새로운 배열을 만들고 모든 것을 복사 한 다음 이전 배열을 파괴해야합니다. 배열이 커질수록이 작업이 더 비싸고 소비되는 메모리가 많아지고 스크립트가 더 느려집니다. 그것은 임의의 일반적인 O (n) 복잡도 루프를 O (n^2) 복잡도 루프로 변환합니다.

은 즉,이 작업을 수행해야 하나 의미

$Array = $x | ForEach-Object { [...] } 

또는이 :

$Array = New-Object -TypeName System.Collections.ArrayList; 
$x | ForEach-Object { 
    $Record = [...] 
    $Array.Add($Record) 
} 

여기 동적 헤더를 가져옵니다 무언가의 예입니다. 이 경우 C:\Windows\에 처음 10 개의 파일에 대한 String 및 DateTime 형식의 모든 속성을 가져옵니다.

# Get the data 
$Data = Get-ChildItem C:\Windows\ -File | Select-Object -First 10; 

# Get the headers that meet our criteria 
# It's not important what this code is doing, it's just establishing headers 
# dynamically 
$Headers = $Data[0].PSObject.Properties | 
    Where-Object TypeNameOfValue -in @('System.String', 'System.DateTime') | 
    Select-Object -ExpandProperty Name; 

# Iterate through the Data 
$Results = $Data | ForEach-Object { 
    # Create a hash table to save the properties in. 
    $Record = @{}; 

    # For each header, create a property in the hash table and assign it the corresponding value from the object in the stream 
    foreach ($Header in $Headers) { 
     $Record.$Header = $_.$Header; 
    } 

    # Convert the hash table we've saved to a PSCustomObject 
    [PSCustomObject]$Record; 
} 

불행히도, 난 $rs가 나 방법을 만드는 모르겠어요. ADO RecordSet과 같은 것으로 추측되지만 논리가 다소 벗어납니다. (이것은 내가하고 RecordSet.MoveFirst()을 기억 어떤 않는 경우는 잘못된 루프,하지만 내가 misremembering 할 수있다처럼 즉, $rs.MoveFirst() 보입니다.)

여기 아이디어는 그러나 동일합니다. 까지

+0

문제는 많은 다른 테이블에서 작동하기 때문에 이름, 전체 이름 및 CreationDate가있는 사용자 지정 개체를 만들 때 하드 코드가 작동하지 않습니다. 가져 오려는 다음 표에는 해당 3 개의 열이 없을 수 있기 때문입니다. 그래서 저는 컬럼과 레코드의 수를 기반으로 루프를 수행하려고합니다. 그러나 배열에 대한 헤드 업에 감사 드리며, 더 효율적으로 변경했습니다. – matt

+0

@matt 여전히 그렇게 할 수 있습니다. '$ rs'가 무엇인지, 또는 그 타입의 객체를 만드는 방법을 모르므로 구체적인 답을 줄 수는 없습니다. 실행 시간에 헤더를 결정하는 예제는 최신 코드를 참조하십시오. –

+0

도와 주셔서 감사합니다. – matt

0
$resultsArray = New-Object -TypeName System.Collections.ArrayList; 
$ColumnCount = 0; 
$contactObject = new-object PSObject; 

if ($rs.RecordCount -ne 0){ 

$rs.MoveFirst() 

do { 
$ColumnCount = 0; 
do{ 
$columnHeader = $rs.fields.item($ColumnCount).name 
$value = $rs.Fields.Item($columnHeader).Value; 

$contactObject | add-member -membertype NoteProperty -name $columnHeader - 
Value $value; 

$columncount++ 

}until($ColumnCount -eq $rs.fields.count) 

$resultsArray.add($contactObject) 
$rs.MoveNext()   
$contactObject= new-object PSObject; 

} 내가 그것을했다

} 

} 
    $resultsarray 

($ rs.EOF -eq $ 참) !!!! 트릭은 배열에 레코드를 추가 한 다음 객체, add-member를 삭제하고 배열에 추가하고 객체를 지우는 것이 었습니다 ..... 굉장합니다!