Changing metadata of an image object using DocumentObj 2.5 SetMetaData

I'm wring a PowerShell script to change objects metadata at once. My script woks properly for topic objects. However, it does not work for image objects. I wrote the following code to change metadata using DocumentObj 2.5.

function DocumentObj-SetMetaData()
{
  $functionName = "DocumentObj-SetMetaData"
  $documentObjUrl = $infosharewsurl + "DocumentObj25.asmx?WSDL"
  $documentObjWebService = new-webServiceProxy -uri $documentObjUrl -UseDefaultCredential
  try
  {
    $psXMLMetadata = "<ishfields>"
    $psXMLMetadata += "<ishfield name='FTITLE' level='logical'>" + $ftitle + "</ishfield>"
    $psXMLMetadata += "<ishfield name='FKUBOTAMODELCLASSIFICATION' level='version'>" + $classification + "</ishfield>"
    $psXMLMetadata += "<ishfield name='FKUBOTAMODELSERIES' level='version'>" + $modelseries + "</ishfield>"
    $psXMLMetadata += "<ishfield name='FKUBOTAMODEL' level='version'>" + $model + "</ishfield>"
    $psXMLMetadata += "<ishfield name='FKUBOTAREGION' level='version'>" + $region + "</ishfield>"
    $psXMLMetadata += "<ishfield name='FKUBOTACOUNTRY' level='version'>" + $country + "</ishfield>"
    $psXMLMetadata += "<ishfield name='FKUBOTAKEYWORD' level='version'>" + $keywords + "</ishfield>"
    $psXMLMetadata += "</ishfields>"
  
    $psXMLRequiredCurrentMetadata = "<ishfields/>"
  
    # Write-Host($psXMLMetadata)
    Write-Host($id)
    $result = $documentObjWebService.SetMetaData([REF]$context, $id, [REF]$version, $language, $resolution, $psXMLMetadata, $psXMLRequiredCurrentMetadata)
  }
  catch [System.Web.Services.Protocols.SOAPException]
  {
    ("error at " + $functionName)
      Return-Result $Error[0].Exception.InnerException.Message
  }

  $result #returning the function value by simply outputting it
}
When this function is called, following ishfields are given via $psXMLMetadata variable.
<ishfields>
  <ishfield name='FTITLE' level='logical'>OM-GUIDE-0001</ishfield>
  <ishfield name='FKUBOTAMODELCLASSIFICATION' level='version'></ishfield>
  <ishfield name='FKUBOTAMODELSERIES' level='version'></ishfield>
  <ishfield name='FKUBOTAMODEL' level='version'></ishfield>
  <ishfield name='FKUBOTAREGION' level='version'></ishfield>
  <ishfield name='FKUBOTACOUNTRY' level='version'></ishfield>
  <ishfield name='FKUBOTAKEYWORD' level='version'>guide</ishfield>
  <ishfield name='FRESOLUTION' level='lng'>Thumbnail</ishfield>
</ishfields>
An exception occurs when the $documentObjWebService.SetMetaData is executed and it returns '-102003' as the error code. I looked into the error code explanation in the following page. But I cannot figure out the reason of the error.
Please give me advises to resolve this issue.
Kind regards,
Naoki
Parents Reply Children
  • Hi Dave,

    This PowerShell code was given by a SDL support engineer and had been working well for map/topic objects. This is reason why I'm using the deprecated ASMX-SOAP API functions. Regarding ISHRemote, there isn't enough information and I didn't realize it works as the alternative of the ASMX-SOAP API functions.

    We are using TD14 SP1 so that ISHRemote works on it. I'll try ISHRemote by referring your suggested code.

    Thank you for good suggestion.

    Kind regards,

    Naoki

  • Umm, it's difficult.

    I'm trying to get/set object's metadata based on object id (i.e. GUID) and its version. Therefore, I created a CSV file that contains GUID and its version of objects as shown below.

    GUID-CA754C5A-A4FC-44E4-9BA9-7A7EC19215E3,1
    GUID-806E1FE4-083A-4B45-A9F1-6177A987EBB7,1
    GUID-DDF07E67-29C7-49DF-8676-90C1AD9A311E,1

    In the PowerShell script, I want to process each object by finding the object using Find-IshDocumentObj. However, it seems specifying GUID for Set-IshMetadataFilterField is not possible. How do I process each document object base on the GUID?

    Following is part of my PowerShell code:
    # Read CSV file that contains GUID and its version list
    $input_csv = Get-Content $obj_list_csv | ConvertFrom-Csv -Header @('GUID''version')

    # Get matadata for each object
    $input_csv | ForEach-Object {
      $cur_GUID = $_."GUID"
      $cur_version = $_."version"
      # Write-Host ($cur_GUID,"`t",$cur_version)
      $obj_filer = Set-IshMetadataFilterField -IshSession $ishSession -Level logical -Name IshRef -FilterOperator Equal -Value $cur_GUID |
                   Set-IshMetadataFilterField -Level version -Name VERSION -FilterOperator Equal -Value $cur_version | 
                   Set-IshMetadataFilterField -Level lng -Name DOC-LANGUAGE -FilterOperator Equal -Value $lang
      $ishObject = Find-IshDocumentObj -IshSession $ishSession -MetadataFilter $obj_filer
      $documentDescription = "$($ishObject.IshRef)=$($ishObject.version_version_value)=$($ishObject.doclanguage)"
      Write-Host "$documentDescription"
    }
  • In essence the ASMX-SOAP and WCF-SOAP are equal regarding business calls, but differ in the security paradigm they respect. So I'm not forcing you into ISHRemote. Some background on the API and its future is available here: https://community.sdl.com/product-groups/sdl-tridion/tridion-docs/m/videos/4533 

    As I developed on ISHRemote I think it does its best to wrap WCF-SOAP in a PowerShell pipeline object friendly way. The ASMX-SOAP will force you more in raw xml structures.

    On the essence, finding one object by GUID. That is actually the main difference between a Find-* and Get-* cmdlet, with Find-* you do not know the identifier, with Get-* you do (as in your scenario). So regarding the last piece of code, what about:

    $metadataFilter = Set-IshMetadataFilterField -Level Version -Name VERSION -FilterOperator Equal -Value $cur_version |
                    Set-IshMetadataFilterField -Level Lng -Name DOC-LANGUAGE -FilterOperator Equal -Value $lang
    Get-IshDocumentObj -LogicalId $cur_GUID -MetadataFilter $metadataFilter
    # and ISHRemote already takes care of the returned object in pretty-print for you and retrieves a bunch of nice descriptive fields for you

    And on https://github.com/sdl/ISHRemote are some extra links, also ISHRemote repects the Get-Help some-cmdlet principle with examples.

  • I'm getting familiar with ISHRemote and PowerShell. I succeeded to obtain objects metadata based on object's GUID and version. This could be achieved with your kind assistance. Thanks a lot, Dave!

    Now, it's possible to add or modify metadata using Excel. My next task is writing a PowerShell script that overwrite objects metadata. As the result, we'll be able to add or modify metadata for a publication at once.

    # Get objects metadata from TD14 UAT server
    # [Command syntax]
    # > GetMetaFromUAT.ps1 <obj_list_csv> <out_meta_tsv> <lang>

    # Get command line arguments and check them
    Param($obj_list_csv, $out_meta_tsv, $lang)
    if ([string]::IsNullOrEmpty($obj_list_csv) -or [string]::IsNullOrEmpty($out_meta_tsv) -or [string]::IsNullOrEmpty($lang)) {
      Write-Error("Error: Three arguments (obj_list_csv, out_meta_tsv, lang) must be specified.")
      break
    }

    #Provide Web Services URL
    $url = 'https://xxxxxxx/ISHWS/'

    #Provide Domain and your username
    $username = 'xxxxx'
    $password = 'xxxxx'

    # Check for file existence
    if (-not(Test-Path $obj_list_csv)) {
      Write-Error("Error: Specified CSV file does not exist.")
      break
    }

    # login to Content Manager
    try {
      $ishSession = New-IshSession -WsBaseUrl $url -IshUserName $username -IshPassword $password
    catch {
      Write-Host "Cannot connect ...."
      exit
    }

    # Read CSV file that contains GUID and its version list
    $input_csv = Get-Content $obj_list_csv | ConvertFrom-Csv -Header @('GUID''version')

    # Create output file and write header line in it
    $outputFile = New-Object System.IO.StreamWriter($out_meta_tsv, $false, [Text.Encoding]::GetEncoding("UTF-16"))
    $outputFile.WriteLine("GUID`tVersion`tTitle`tModel classification`tModel series`tModel`tRegion`tCountry`tKeywords`tResolution")

    # Get matadata for each object
    $input_csv | ForEach-Object {
      $cur_GUID = $_."GUID"
      $cur_version = $_."version"
      Write-Host ($cur_GUID)
      $metadataFilter = Set-IshMetadataFilterField -IshSession $ishSession -Level version -Name "VERSION" -FilterOperator Equal -Value $cur_version | Set-IshMetadataFilterField -IshSession $ishSession -Level lng -Name "DOC-LANGUAGE" -FilterOperator Equal -Value $lang  | Set-IshMetadataFilterField -IshSession $ishSession -Level lng -Name "FRESOLUTION" -FilterOperator Equal -Value "Thumbnail"
      $target_obj = Get-IshDocumentObj -IshSession $ishSession -LogicalId $cur_GUID -MetadataFilter $metadataFilter
      $title = ($target_obj.IshField | where Name -eq FTITLE).value
      $modelClassification = ($target_obj.IshField | where Name -eq KUBOTAMODELCLASSIFICATION).value
      $modelSeries = ($target_obj.IshField | where Name -eq FKUBOTAMODELSERIES).value
      $model = ($target_obj.IshField | where Name -eq FKUBOTAMODEL).value
      $region = ($target_obj.IshField | where Name -eq FKUBOTAREGION).value
      $country = ($target_obj.IshField | where Name -eq FKUBOTACOUNTRY).value
      $keyword = ($target_obj.IshField | where Name -eq FKUBOTAKEYWORD).value
      $resolution = ($target_obj.IshField | where Name -eq FRESOLUTION).value
      # Write to file as tab separated values
      $outputFile.WriteLine($cur_GUID,"`t",$cur_version,"`t",$title,"`t",$modelClassification,"`t",$modelSeries,"`t",$model,"`t",$region,"`t",$country,"`t",$keyword,"`t",$resolution)
    }