2012-03-29 7 views
1

現在、PowerShellでいくつかの配列を作成していますが、コードを移植性の高いものにするために、XMLファイルを各配列の処理方法を管理するよりシンプルな方法その目的。Powershell、XML&Arrays

アレイ1は、rownumber、名前、保持およびタイプを含む情報のマスターリストです。

<?xml version="1.0" encoding="UTF-8"?> 
<ZipList> 
    <Backup RowID="1"> 
     <RowNbr>1</RowNbr> 
     <NameType>TargetBackup</NameType> 
     <Retention>10</Retention> 
     <FileType>Folder</FileType> 
    </Backup> 
    <Backup RowID="2"> 
     <RowNbr>2</RowNbr> 
     <NameType>SourceBackup</NameType> 
     <Retention>7</Retention> 
     <FileType>Folder</FileType> 
    </Backup> 
    <Backup RowID="3"> 
     <RowNbr>3</RowNbr> 
     <NameType>XMLBackup</NameType> 
     <Retention>21</Retention> 
     <FileType>File</FileType> 
    </Backup> 
</ZipList> 

私は現在、私は後でそれを通してループに使用し、同様のハッシュテーブルを構築するために構築配列:私はこのように見えるようにXMLのためにしたいと思います。だから、私は本当にPowerShellスクリプトの残りの部分を再エンジニアリングしたくはありません。

しかし、(スクリプト内の配列を変更するのではなく)XMLファイルを変更する方が簡単なので、XMLファイルでこの配列を複製するだけです。これは少し簡単です&自己文書化して変更を加え、このXMLファイルを読み込み、現在作成中の配列に保存します。

xmlファイルを読み込むことができますが、xmlデータを配列に取り込むことができません。上記のXML例えば、配列は次のようになります。

counter ++ 
arr1 += ,@(counter,1,"TargetBackup",10,"Folder") 
counter ++ 
arr1 += ,@(counter,2,"SourceBackup",7,"Folder") 
counter ++ 
arr1 += ,@(counter,3,"XMLBackup",21,"File") 

など....私が午前

問題は、XMLデータが入っているということですが、それは私の文字列です一度にそれをつかむ以外には何もできません。任意の助け、提案は高く評価されました。

答えて

2

なぜその配列をclixmlとしてエクスポートしないのですか?その後、移植性があり、スクリプトでそれを使用したいときは、それを再インポートして、配列を元に戻します。

+0

最初に、私はそれをしました。 XML内の構造と命名規則はあまり有益ではありませんでした。私はカスタマイズできるとは思っていませんでした。 –

+1

データを見ると、.csvファイルを使用できないXML形式のものは見当たらないし、スクリプトの内部と外部の両方を処理する方がはるかに簡単です。私見では。 – mjolinor

+0

私もそれを考慮していなかった - あなたは110%正しいです。私が考慮しなかった明らかな解決策を提案していただきありがとうございます。 –

1

フォローアップと同様に、以下は私が行ったコードです。 Mjolinorの CSVファイルを使用して解決策を単純化(相対的に話す)することの提案(ありがとう)。私は間違いなく解決策を複雑にしようとしていました。

私はプロセスを駆動するために使用した3つのCSVファイルを作成しました。最初に、RotateBackups_Masterlist.txtファイルがあります。 BackupNameは、後でプロセスに関連付けられるバックアップの名前です。 VersionsRetainedは手元にある番号です。 BackupTypeは、それがファイルバックアップであるかフォルダバックアップであるかです。

RowNbr,BackupName,VersionsRetained,BackupType 
1,TargetBackup,2,Folder 
2,LstDefBackup,5,File 
3,XMLBackup,3,File 
4,SourceBackup,2,Folder 
5,TXTBackup,8,File 

2番目のファイルはRotateBackups_FolderList.txtです。 BackupNameは上記のファイルの同じフィールドに対応し、Foldernameはバックアップされているフォルダです。

RowNbr,BackupName,FolderName 
1,TargetBackup,c:\MyBooks\target 
2,SourceBackup,c:\MyBooks\source 

3番目のファイルはRotateBackups_FileExtensions.txtです。 BackupNameは最初のファイルの同じフィールドに対応し、FileExtensionはバックアップされるファイルのワイルドカード名(パターンも受け入れます)、FolderLocはこれらの項目が見つかるフォルダです。

RowNbr,BackupName,FileExtension,FolderLoc 
1,LstDefBackup,*.def,c:\MyBooks\target 
2,LstDefBackup,*.lst,c:\MyBooks\target 
3,XMLBackup,*.xml,c:\MyBooks\target 
4,TXTBackup,*.txt,c:\MyBooks\rfiles 

複数のBackupNamesに同じファイル拡張子をバックアップできます。また、複数のフォルダを同じBackupNameとFileExtensionに割り当てることができます。それは何

  • それは、ファイル名に BackupNameフィールド(マスターファイル)にちなんで命名され、その中にzipファイルとフォルダのプラス日時スタンプ( 同じバッチ内のすべて)を作成します。
  • ファイル名のバッチ日付と時刻はすべて同じですので、 は、20120401_091500.zipで終わるバックアップがすべて同じ実行で作成された であることを認識します。
  • バックアップのバージョンを指定することができ、復元先の時刻は になります。
  • バックアップスペースの管理に柔軟性があります。 の要件。それはあなたに重要なバックアップのためのより長い保持 を維持する能力を提供しますか、またはより重要でないもののためのより短い保持を維持します。
  • 削除されたアイテムは破壊的に削除またはリサイクルできます。
  • バックアップは作成日に基づいて期限切れになりません。バックアップの対象となるのは の唯一のもので、保持する番号の上にカウントを置くより新しいものの作成 です。私は直前のファイルを削除する 空の配列やLASTEXITCODEをチェックする以外のことでのエラー処理の多くを、持っていない

    • :それは行いません何

  • バックアップは一度に1つずつ、 ファンクションコールでzipファイルを作成/更新するので、同じ種類のファイルが膨大な数になることはありません。 がファイル拡張子を使用してバックアップされています。

最後に、作業を行うコード(コメントの後に全体として投稿)。私は多くの情報源から多くの部分のコードを手に入れ、それぞれのオリジナルポスター/開発者に感謝します。このユーティリティの使用は、自己責任で行ってください。私は他の人がこれに追加したいかもしれない改善を歓迎する。

これはバックアップを作成する機能です。

function create-7zip([String] $aDirectory, [String] $aZipfile){ 
    [string]$pathToZipExe = "C:\Program Files\7-zip\7z.exe"; 
    [Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r"; 
    & $pathToZipExe $arguments; 
} 
# Call it by using: 
#create-7zip "c:\temp\myFolder" "c:\temp\myFolder.zip" 

変数&配列が、ここでは初期化されている上からテキストファイルがここにインポートされます。変数$ KillOrRecycleはリサイクルに設定されているため、削除されたものはごみ箱に送られます。 Killは、破壊的で回復不能なファイルの削除です。

#************************************************************************************ 
#************************************************************************************ 
# Initialize variables 
$zipFolder = "C:\ZipFiles" 
$nameConv = "{0:yyyyMMdd_HHmmss}" -f (Get-Date) + ".zip" 
$fileList = @{} 
$FileCountArray = @() 
$bkupTypeArr = @() 
$myDocFolder = "c:\Documents and Settings\MyPC\My Documents\" 

# Import text files for master, folder and file backup information 
$bkupRotateMasterArr = Import-Csv $myDocFolder"RotateBackups_MasterList.txt" 
$fldrBkupArray = Import-Csv $myDocFolder"RotateBackups_FolderList.txt" 
$fileExtBkupArr = Import-Csv $myDocFolder"RotateBackups_FileExtensions.txt" 

# Switch to delete Item or to send to recycle bin 
#  delete is destructive and cannot recover file. 
#  Recycle setting removes file from folder, but sends to recycle bin 
#  and can be restored if needed. 
#  Must be either "Kill" or "Recycle" 
$KillOrRecycle = "Recycle" 
#************************************************************************************ 
#************************************************************************************ 

インポートされたCSVファイルの内容をハッシュテーブルに読み込みます。
$ bkup_CountsはBackupNameのハッシュテーブルです&保持するファイルの数。

$ bkupTypeArr(上で後に使用)BackupNamesのアレイは

$ fArrayはBackupNameのハッシュテーブルであり、ファイル名は、それは、それに関連付けられて生成されます。
$ nameConvは、この実行のすべてのファイルに同じ日付と時刻のスタンプを与えるために先頭で行われます。

# Load contents of master backup array 
$bkup_Counts = @{} 
$b = $null 
foreach($b in $bkupRotateMasterArr) 
    { 
    $bkup_Counts[$b.BackupName] = $b.VersionsRetained 
    } 


#set Backup Types from the array we just defined 
$type = $null 
foreach ($type in $bkup_Counts.Keys) { 
    $bkupTypeArr += $type 
    } 

#create array of our filenames for this batch 
$type = $null 
$fArray = @{} 
foreach ($type in $bkupRotateMasterArr) { 
    $fArray[$type.BackupName] = ($type.BackupName + $nameConv) 
     } 

我々はfileExtension配列内のすべてのデータを持っている場合次に、適切なBackupNameと関連付け、そのパスから、それに一致するすべてのものをつかむために、フォルダの場所&ファイルの拡張子(再帰的に)を使用して、それを介して実行します。それを、キーとしてfullnameプロパティを持ち、関連付けられている値としてBackupNameを持つ$ filelistハッシュテーブルに追加します。

# if extension array not null, get list of files to back up 
if ($fileExtBkupArr) {  
    # Gather the list of files to be backed up 
    $f = $null 
    foreach ($f in $fileExtBkupArr) { 
      $arr = @() 
      $arr = (Get-ChildItem $f.FolderLoc -Recurse -Include $f.FileExtension | Select-Object fullname) 
      foreach ($a in $arr) { 
       if ($a) { 
       $fileList[$a] = $f.BackupName 
       } # if $a not null 
      } # end inner foreach 
     } # end outer foreach 
} # if FileExtension Backup Array not null 

次に、filelistハッシュテーブルに何かがある場合は、適切な名前のバックアップに圧縮します。

# if filelist count gt zero, then create zip file of them for appropriate backup 
if ($fileList.Count -gt 0) { # must have entries in hashtable 
    $f = $null 
    #Loop thru file list & associate file with the appropriate backup 
    foreach ($f in $fileList.Keys) { 
     $arcFile = $null 
     if ($fileList.ContainsKey($f)) { 
      if ($fArray.ContainsKey($fileList[$f])) { 
       $arcFile = $fArray[$fileList[$f]] 
       create-7zip $f.FullName $zipFolder\$arcFile 
      } #if key in fArray 
     } # if key in Filelist 
    } # end foreach 
} # if hastable not empty 

次に、バックアップするフォルダがある場合は、同様のプロセスを使用して同様の方法でこれらのフォルダをバックアップします。

# if folder backup not null then back up folders 
if ($fldrBkupArray) { # check if array not null (no entries) 
    $f = $null 
    #Backup Folders now 
    foreach ($f in $fldrBkupArray) { 
     $arcFldr = $null 
     #if ($fArray.ContainsKey($f[1])) { 
     if ($fArray.ContainsKey($f.BackupName)) { 
      $arcFldr = $fArray[$f.BackupName] 
      create-7zip $f.FolderName $zipFolder\$arcFldr 
      } #end if 
     } # end foreach 
} # end if $fldrBkupArray not null 

次の項目は、削除する前に何も失敗していないことを確認することです。アーカイブビットが設定されているかどうかに基づいて削除し、削除したファイルをごみ箱(デフォルト)またはビットバケットに送信します。

# if 7zip succeeded, we'll continue 
if ($LASTEXITCODE -gt 0) 
    {Throw "7Zip failed" } 
ELSE { # if Exitcode = 0 then continue with job 
    # Remove any files with Archive bit = False 
    # we marked it for deletion in previous run 
    Add-Type -AssemblyName Microsoft.VisualBasic 
    $files=get-childitem -path $zipFolder 
    # we'll delete all files that don't have the archive bit set 
    Foreach($file in $files) { 
     If((Get-ItemProperty -Path $file.fullname).attributes -band [io.fileattributes]::archive) 
     { Write-output "$file is set to be retained" } 
     ELSE { 
      if ($KillOrRecycle = "Recycle") { 
       Write-output "$file does not have the archive bit set. Deleting (Sent to recycle bin)." 
       [Microsoft.VisualBasic.FileIO.Filesystem]::DeleteFile($file.fullname,'OnlyErrorDialogs','SendToRecycleBin') 
       $output = $_.ErrorDetails 
       } 
      ELSE { 
       Write-output "$file does not have the archive bit set. Deleting." 
       remove-item -recurse $file.fullname 
       $output =$_.ErrorDetails 
       } 
      } 
     } #end Foreach 

次に、アーカイブフォルダ内のファイル(BackupNameの種類別)をカウント、xmlファイルにBackupName &カウントをエクスポートし、我々は削除のために余分なものをマークすることができますように、すべてのファイルにアーカイブビットを設定します。今

# Export BackupCounts to XML 
$bkup_counts | Export-Clixml bkup_counts.xml 

# Get Number of ZIP files in folder 
$btype = $null 
foreach ($btype in $bkupTypeArr) { 
    $FileCountArray += ,@(($btype),(dir $zipFolder\$btype"*.zip").count) 
    } 

# Import BkupCounts from XML 
$bkup_Counts= Import-Clixml bkup_counts.xml 

# set Attribute byte on ALL files in zipfolder so we know we'll get the right ones 
attrib $zipFolder"\*" +a 

、BackupNameパターンに一致するファイルの数を取得し、ファイルの数のカウントから保持の日数を差し引い、bkup_Countsハッシュテーブルスルー戻ります。差が0より大きい場合、そのフォルダからその数のエントリを削除する必要があります。

同じBackupNameパターンを使用してフォルダをパイプし、Creation Timeプロパティでソートし、最初のN個のファイルを選択します(Nは上記の保持値で0より大きい数字です)。

次に、選択したオブジェクトごとに、&に戻り、アーカイブビットをFALSEに設定して、次の実行時に削除のマークを付けます。

$row = $null 
    # Get LST & DEF filenames in array & display count 
    foreach ($row in $bkup_Counts.Keys) { 
     Get-ChildItem -Path $zipFolder -Include $row"*" -Recurse #| 
     (dir $zipFolder\$row"*".zip).count - $bkup_Counts[$row] 
     $delfiles = 0 
     $delfiles = (dir $zipFolder\$row"*".zip).count - $bkup_Counts[$row] 
     if ($delfiles -gt 0) { #sort folder by createdtime 
      # if more than specified nbr of backups present, un-archive excess ones to delete next run. 
      dir $zipFolder\$row"*" | sort-object -property {$_.CreationTime} | 
      select-object -first $delfiles | 
      foreach-object { attrib $_.FULLNAME -A} 
      } # end if delfiles gt 0 
     } # End foreach in bkup_counts 

} # End Else Last ExitCode = 0  

ここにコード全体があります。

function create-7zip([String] $aDirectory, [String] $aZipfile){ 
    [string]$pathToZipExe = "C:\Program Files\7-zip\7z.exe"; 
    [Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r"; 
    & $pathToZipExe $arguments; 
} 
# Call it by using: 
#create-7zip "c:\temp\myFolder" "c:\temp\myFolder.zip" 

#************************************************************************************ 
#************************************************************************************ 
# Initialize variables 
$zipFolder = "C:\ZipFiles" 
$nameConv = "{0:yyyyMMdd_HHmmss}" -f (Get-Date) + ".zip" 
$fileList = @{} 
$FileCountArray = @() 
$bkupTypeArr = @() 
$myDocFolder = "c:\Documents and Settings\MyPC\My Documents\" 

# Import text files for master, folder and file backup information 
$bkupRotateMasterArr = Import-Csv $myDocFolder"RotateBackups_MasterList.txt" 
$fldrBkupArray = Import-Csv $myDocFolder"RotateBackups_FolderList.txt" 
$fileExtBkupArr = Import-Csv $myDocFolder"RotateBackups_FileExtensions.txt" 

# Switch to delete Item or to send to recycle bin 
#  delete is destructive and cannot recover file. 
#  Recycle setting removes file from folder, but sends to recycle bin 
#  and can be restored if needed. 
#  Must be either "Kill" or "Recycle" 
$KillOrRecycle = "Recycle" 
#************************************************************************************ 
#************************************************************************************ 

# Load contents of master backup array 
$bkup_Counts = @{} 
$b = $null 
foreach($b in $bkupRotateMasterArr) 
    { 
    $bkup_Counts[$b.BackupName] = $b.VersionsRetained 
    } 


#set Backup Types from the array we just defined 
$type = $null 
foreach ($type in $bkup_Counts.Keys) { 
    $bkupTypeArr += $type 
    } 

#create array of our filenames for this batch 
$type = $null 
$fArray = @{} 
foreach ($type in $bkupRotateMasterArr) { 
    $fArray[$type.BackupName] = ($type.BackupName + $nameConv) 
     } 

# if extension array not null, get list of files to back up 
if ($fileExtBkupArr) {  
    # Gather the list of files to be backed up 
    $f = $null 
    foreach ($f in $fileExtBkupArr) { 
      $arr = @() 
      $arr = (Get-ChildItem $f.FolderLoc -Recurse -Include $f.FileExtension | Select-Object fullname) 
      foreach ($a in $arr) { 
       if ($a) { 
       $fileList[$a] = $f.BackupName 
       } # if $a not null 
      } # end inner foreach 
     } # end outer foreach 
} # if FileExtension Backup Array not null 


# if filelist count gt zero, then create zip file of them for appropriate backup 
if ($fileList.Count -gt 0) { # must have entries in hashtable 
    $f = $null 
    #Loop thru file list & associate file with the appropriate backup 
    foreach ($f in $fileList.Keys) { 
     $arcFile = $null 
     if ($fileList.ContainsKey($f)) { 
      if ($fArray.ContainsKey($fileList[$f])) { 
       $arcFile = $fArray[$fileList[$f]] 
       create-7zip $f.FullName $zipFolder\$arcFile 
      } #if key in fArray 
     } # if key in Filelist 
    } # end foreach 
} # if hastable not empty 

# if folder backup not null then back up folders 
if ($fldrBkupArray) { # check if array not null (no entries) 
    $f = $null 
    #Backup Folders now 
    foreach ($f in $fldrBkupArray) { 
     $arcFldr = $null 
     #if ($fArray.ContainsKey($f[1])) { 
     if ($fArray.ContainsKey($f.BackupName)) { 
      $arcFldr = $fArray[$f.BackupName] 
      create-7zip $f.FolderName $zipFolder\$arcFldr 
      } #end if 
     } # end foreach 
} # end if $fldrBkupArray not null 


# if 7zip succeeded, we'll continue 
if ($LASTEXITCODE -gt 0) 
    {Throw "7Zip failed" } 
ELSE { # if Exitcode = 0 then continue with job 
    # Remove any files with Archive bit = False 
    # we marked it for deletion in previous run 
    Add-Type -AssemblyName Microsoft.VisualBasic 
    $files=get-childitem -path $zipFolder 
    # we'll delete all files that don't have the archive bit set 
    Foreach($file in $files) { 
     If((Get-ItemProperty -Path $file.fullname).attributes -band [io.fileattributes]::archive) 
     { Write-output "$file is set to be retained" } 
     ELSE { 
      if ($KillOrRecycle = "Recycle") { 
       Write-output "$file does not have the archive bit set. Deleting (Sent to recycle bin)." 
       [Microsoft.VisualBasic.FileIO.Filesystem]::DeleteFile($file.fullname,'OnlyErrorDialogs','SendToRecycleBin') 
       $output = $_.ErrorDetails 
       } 
      ELSE { 
       Write-output "$file does not have the archive bit set. Deleting." 
       remove-item -recurse $file.fullname 
       $output =$_.ErrorDetails 
       } 
      } 
     } #end Foreach 

    # Export BackupCounts to XML 
    $bkup_counts | Export-Clixml bkup_counts.xml 

    # Get Number of ZIP files in folder 
    $btype = $null 
    foreach ($btype in $bkupTypeArr) { 
     $FileCountArray += ,@(($btype),(dir $zipFolder\$btype"*.zip").count) 
     } 

    # Import BkupCounts from XML 
    $bkup_Counts= Import-Clixml bkup_counts.xml 

    # set Attribute byte on ALL files in zipfolder so we know we'll get the right ones 
    attrib $zipFolder"\*" +a 

    $row = $null 
    # Get LST & DEF filenames in array & display count 
    foreach ($row in $bkup_Counts.Keys) { 
     Get-ChildItem -Path $zipFolder -Include $row"*" -Recurse #| 
     (dir $zipFolder\$row"*".zip).count - $bkup_Counts[$row] 
     $delfiles = 0 
     $delfiles = (dir $zipFolder\$row"*".zip).count - $bkup_Counts[$row] 
     if ($delfiles -gt 0) { #sort folder by createdtime 
      # if more than specified nbr of backups present, un-archive excess ones to delete next run. 
      dir $zipFolder\$row"*" | sort-object -property {$_.CreationTime} | 
      select-object -first $delfiles | 
      foreach-object { attrib $_.FULLNAME -A} 
      } # end if delfiles gt 0 
     } # End foreach in bkup_counts 

} # End Else Last ExitCode = 0  
関連する問題