Project Server 上的 PSI 更新查找 table - 错误 "LookupTableAlreadyExists"

PSI update lookup table on Project Server - error "LookupTableAlreadyExists"

我正在编写一个脚本,该脚本将使用 PSI 更新 Project Server 2013 的企业自定义字段和查找表。 该脚本从一个系统导出的 XML 文件中获取设置,然后更新另一个系统上的设置。

程序如下: skript 从目标系统获取当前的 LookupTableDataSet。然后它会添加、修改或删除该数据集上的查找表、条目和掩码。内置查找表未以任何方式修改。最后它将修改后的数据集传递给 UpdateLookupTables 方法以更新目标系统。

问题: 目标系统不断返回 "LookupTableAlreadyExists" 错误。它对所有已修改或未更改的查找表执行此操作。已删除或添加的查找表不会引发此错误。

代码如下:

$defaultLookupsEN = @("Cost Type", "Department", "Health", "RBS", "Relative Importance", "Project Impact")

function updateLookupTables($dataset) {
  $importPath = "$inXMLPath\LookupTables.xml"
  $lookupTablesXML = Import-Clixml $importPath

  $existingLookupTableNames = $dataset.LookupTables.Rows.LT_NAME
  $existingLookupTablesFullData = $dataset
  $existingTableIDs = $dataset.LookupTables.Rows.LT_UID

  foreach ($lookupTable in $lookupTablesXML) {
    if ($existingLookupTablesFullData.LookupTables.LT_UID.Contains($lookupTable.LT_UID)) {
        # if source table already exists on target system, update existing table

        # Do not update built-in lookup tables
        if($lcid -eq 1031 -and $defaultLookupsDE.Contains($lookupTable.LT_NAME)){
            continue;
        }
        if($lcid -eq 1033 -and $defaultLookupsEN.Contains($lookupTable.LT_NAME)){
            continue;
        }

        # Get current lookup table by UID
        $lookupRow = $existingLookupTablesFullData.LookupTables.Rows | ? {$_.LT_UID -eq $lookupTable.LT_UID}

        #add lookup values from xml
        $lookupRow.LT_NAME = [string] $lookupTable.LT_NAME
        $lookupRow.LT_SORT_ORDER_ENUM = [int] $lookupTable.LT_SORT_ORDER_ENUM
        $lookupRow.LT_PRIMARY_LCID = [int] $lookupTable.LT_PRIMARY_LCID
        $lookupRow.LT_FILL_ALL_LEVELS = [boolean] $lookupTable.LT_FILL_ALL_LEVELS

    } else {
        # if source table does not exists on target system, create new table

        # Do not update built in lookup tables
        if($lcid -eq 1031 -and $defaultLookupsDE.Contains($lookupTable.LT_NAME)){
            continue;
        }
        if($lcid -eq 1033 -and $defaultLookupsEN.Contains($lookupTable.LT_NAME)){
            continue;
        }

        $lookupRow = $existingLookupTablesFullData.LookupTables.NewLookupTablesRow();

        #add lookup values from xml
        $lookupRow.LT_UID = [Guid] $lookupTable.LT_UID
        $lookupRow.LT_NAME = [string] $lookupTable.LT_NAME
        $lookupRow.LT_SORT_ORDER_ENUM = [int] $lookupTable.LT_SORT_ORDER_ENUM
        $lookupRow.LT_PRIMARY_LCID = [int] $lookupTable.LT_PRIMARY_LCID
        $lookupRow.LT_FILL_ALL_LEVELS = [boolean] $lookupTable.LT_FILL_ALL_LEVELS

        $existingLookupTablesFullData.LookupTables.AddLookupTablesRow($lookupRow);

        $ltName = $lookupRow.LT_NAME
    }
  }

  for($i = 0; $i -lt $existingLookupTablesFullData.LookupTables.LT_UID.Length; $i++) {
    # remove Lookup tables which are not in source file
    if(!$lookupTablesXML.LT_UID.Contains($existingLookupTablesFullData.LookupTables.Rows.LT_UID[$i])) {
        $existingLookupTablesFullData.LookupTables.Rows[$i].delete()
    }
  }
}

function writeLookupTableDataset($lds) {
    $lookupSvc.UpdateLookupTables($lds, $false, $true, $lcid); 
}

function readExistingLookupTablesDS(){
    return $lookupSvc.ReadLookupTables([system.string]::empty , 0 , $lcid);
}


#------------------- Main Function ---------------------------------

$tablesTarget = readExistingLookupTablesDS

#update the lookup tables and add the rows to the dataset 
updateLookupMasks $tablesTarget
updateLookupEntries $tablesTarget
updateLookupTables $tablesTarget
writeLookupTableDataset $tablesTarget

这是查找表的读数:

$lds.LookupTables.Rows | select LT_NAME, RowState
LT_NAME              RowState
-------              --------
                      Deleted
Cost Category        Modified    -Error
Cost Origin          Modified    -Error
Cost Rate Currency   Modified    -Error
Internal             Modified    -Error
Cost Account         Modified    -Error
Project Impact      Unchanged    -Error
Department          Unchanged    -Error
                      Deleted
Cost Type           Unchanged    -Error
Health              Unchanged    -Error
RBS                 Unchanged    -Error
Relative Importance Unchanged    -Error
Domains                 Added
Test LT                 Added

这里是错误消息(为了更好地理解,我在每行的开头包含了查找表的名称):

<errinfo>
<dataset name="LookupTableDataSet">
<table name="LookupTableMasks">
Cost Category       <row LT_UID="dc2f5020-beae-e911-842b-00155dc61919" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="bbe7bf04-abc8-e911-842b-00155dc61919" /></row>
Cost Origin         <row LT_UID="85417926-beae-e911-842b-00155dc61919" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="bce7bf04-abc8-e911-842b-00155dc61919" /></row>
Cost Rate           <row LT_UID="8986cd2f-beae-e911-842b-00155dc61919" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="bde7bf04-abc8-e911-842b-00155dc61919" /></row>
Internal            <row LT_UID="2215a93c-beae-e911-842b-00155dc61919" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="bee7bf04-abc8-e911-842b-00155dc61919" /></row>
Cost Account        <row LT_UID="8b6cfb6a-beae-e911-842b-00155dc61919" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="bfe7bf04-abc8-e911-842b-00155dc61919" /></row>
Project Impact      <row LT_UID="e8bcec5d-8707-4048-8ff0-4d386457edf7" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="c0e7bf04-abc8-e911-842b-00155dc61919" /></row>
Department          <row LT_UID="e7397277-1ab0-4096-b2dd-57029a055ba4" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="c1e7bf04-abc8-e911-842b-00155dc61919" /></row>
Cost Type           <row LT_UID="0000e630-4965-42b3-a697-88f060891b22" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="c2e7bf04-abc8-e911-842b-00155dc61919" /></row>
Health              <row LT_UID="0000a4aa-160e-499a-905f-d498472dfb35" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="c3e7bf04-abc8-e911-842b-00155dc61919" /></row>
RBS                 <row LT_UID="00008e67-65a3-4898-baaa-d82d995bbb02" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="c4e7bf04-abc8-e911-842b-00155dc61919" /></row>
Relative Importance <row LT_UID="5ad95f2a-cb3e-43d4-b42b-faf2db138590" LT_MASK_STRUCT_LEVEL="1"><error id="11076" name="LookupTableAlreadyExists" uid="c5e7bf04-abc8-e911-842b-00155dc61919" /></row>
</table>
</dataset>
</errinfo>

错误在 updateLookupTableMasks 函数中。 为了提高效率,该函数最初删除了所有查找 table 掩码,并使用更新后的信息创建了新的掩码。事实证明,这会导致错误。必须就地修改查找 table 掩码。

因此我的解决方案是编写一个附加函数,它检查服务器上是否已存在查找 table 掩码,如果不存在则只添加一个新的。