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 掩码,如果不存在则只添加一个新的。
我正在编写一个脚本,该脚本将使用 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 掩码,如果不存在则只添加一个新的。