Question:
I am writing a PowerShell-based XML module for our application configuration needs. Following is the one of the functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
<# .Synopsis To update an XML attribute value .DESCRIPTION In the XML file for a particular attribute, if it contains valueToFind then replace it with valueToReplace .EXAMPLE -------------------------------Example 1 ------------------------------------------------------------------- Update-XMLAttribute -Path "C:\web.Config" -xPath "/configuration/system.serviceModel/behaviors/serviceBehaviors/behavior/serviceMetadata" -attribute "externalMetadataLocation" -valueToFind "http:" -ValueToReplace "https:" Look for the XPath expression with the attribute mentioned and search whether the value contains "http:". If so, change that to "https": .EXAMPLE -------------------------------Example 2 ------------------------------------------------------------------- Update-XMLAttribute -Path "C:\web.Config" -xPath "/configuration/system.serviceModel/behaviors/serviceBehaviors/behavior/serviceMetadata" -attribute "externalMetadataLocation" -valueToFind "http:" -ValueToReplace "https:" Same as Example 1 except that the attribute name is passed as part of the XPath expression #> function Update-XMLAttribute { [CmdletBinding()] [OutputType([int])] Param ( # Web configuration file full path [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Path, # XPath expression up to the parent node [string] $xPath, # This parameter is optional if you mentioned it in xPath itself [string] $attribute, [string] $valueToFind, [string] $ValueToReplace ) Try { If (Test-path -Path $Path) { $xml = New-Object XML $xml.Load($Path) # If the xPath expression itself contains an attribute name then the value of attribute will be processed and taken If ($xPath.Contains("@")) { $xPath, $attribute = $xPath -split '/@', 2 } # Getting the node value using xPath $Items = Select-Xml -XML $xml -XPath $xPath ForEach ($Item in $Items) { $attributeValue = $Item.node.$attribute Write-Verbose "Attribute value is $attributeValue " if ($attributeValue.contains($valueToFind)) { Write-Verbose "In the attribute $attributeValue - $valueToFind is to be repalced with $ValueToReplace" $Item.node.$attribute = $attributeValue.replace($valueToFind, $ValueToReplace) } } $xml.Save($Path) Write-Verbose " Update-XMLAttribute is completed successfully" } Else { Write-Error " The $path is not present" } } Catch { Write-Error "$_.Exception.Message" Write-Error "$_.Exception.ItemName" Write-Verbose " Update-XMLAttribute is failed" } } # End Function Update-XMLAttribute |
As this cmdlet will be consumed by many I don’t think simply writing into console will be the right approach.
As of now in my script if no errors, I can assume that mine is successfully completed.
What is the standard practice to get the results from a PowerShell cmdlet so that the consumer knows whether it is successfully completed or not?
Answer:
The standard practice is to throw exceptions. Each different type of error has a separate exception type which can be used to diagnose further.
Say, file is not represented, you do this:
1 2 3 4 5 |
if (-not (Test-Path $file)) { throw [System.IO.FileNotFoundException] "$file not found." } |
Your cmdlet should document all the possible exceptions it will throw, and when.