I think I've found unexplainable in PowerShell scripting. Let me describe the problem below:
I created a function that will query VSTS and will output back the amount of bugs that contain specific tags.
function GetBugsFromVSTS($applicationName, $first_url, $second_url, $query) {
#Building the body of the HTTP request to VSTS endpoint
$bodyOfRequest = $query | ConvertTo-Json
#Building headers of the HTTP request to VSTS endpoint
$headers = #{
'Content-Type'='application/json'
'Accept'='application/json'
'Authorization' = '' + $vsts_access_token + ''
}
$getBugs = Invoke-RestMethod -Uri $first_url `
-Method Post `
-Body $bodyOfRequest `
-Headers $headers | ConvertTo-Json -Depth 100
$json_decoded = $getBugs | ConvertFrom-Json
if ($json_decoded.workItems -eq $null) {
Write-Host "$applicationName Json decoded workitems are equal null" -ForegroundColor Red
} else {
Write-Host "$applicationName Json decoded workitems are not null" -ForegroundColor Green
$json_decoded.workItems | % {
$bug_id = $_.id
Write-Host $bug_id
}
}
$json_decoded.workItems | % {
$bug_id = $_.id
$url = ($second_url +$bug_id)
$getVstsBugState = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
[PSCustomObject]#{
"Application Name" = $applicationName
"Id" = $bug_id;
"State" = $getVstsBugState.fields.'System.State';
"Reason" = $getVstsBugState.fields.'System.Reason';
"Severity" = $getVstsBugState.fields.'Microsoft.VSTS.Common.Severity'.Substring(4);
"AssignedTo" = $getVstsBugState.fields.'System.AssignedTo'.displayName
}
}
}
When I try to run it
$application = "MyBeautifulApp"
$application_first_url = "https://test.visualstudio.com/72L80E4b-1583-45c1-b669-d8de6133V895/_apis/wit/wiql?api-version=1.0"
$application_second_url = "https://test.visualstudio.com/72L80E4b-1583-45c1-b669-d8de6133V895/_apis/wit/workItems/"
$application_query = #{"query" = "SELECT [System.Id],[System.WorkItemType],[System.Title],[System.AssignedTo],[System.State] FROM WorkItems WHERE [System.TeamProject] = #project AND [System.WorkItemType] = 'Bug' AND [System.Title] CONTAINS 'Test' AND [System.TAGS] CONTAINS 'Test'"}
GetBugsFromVSTS $application $application_first_url $application_second_url $application_query
} catch {
Write-Warning "##vso[task.logissue type=warning;]Some problem occured querying MyBeautifulApp application. Please see below for error details"
$_
}
The most interesting part here is that I'm getting this really weird error message
WARNING: ##vso[task.logissue type=warning;]Some problem occured
querying MyBeautifulApp application. Please see below for error
details
% : You cannot call a method on a null-valued expression.
For the sake of test I added if..else clause to test that $json_decoded.workItems are not equal null, and that verification passes. If I run the code, full output will be
MyBeautifulApp Json decoded workitems are not null
9805
10330
10331
10371
10372
10373
10374
WARNING: ##vso[task.logissue type=warning;]Some problem occured querying MyBeautifulApp application. Please see below for error details
% : You cannot call a method on a null-valued expression. line 29
+ $json_decoded.workItems | % {
+ ~~~
+ CategoryInfo : InvalidOperation: (:) [ForEach-Object], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull,Microsoft.PowerShell.Commands.ForEachObjectCommand
How is it possible that the first verification for $json_decoded.workItems (line 23) is not indicating that variable equals null, whereas the second statement (line 29) shows that it's null?
The problem isn't $json_decoded.workItems, the problem happens inside the script block passed to % / ForEach-Object:
Since you're using an enclosing try / catch handler, the offending individual statement inside the block is, unfortunately, not pinpointed in the error message.
However, given that there's only one method call in your block, the offending line can be inferred:
"Severity" = $getVstsBugState.fields.'Microsoft.VSTS.Common.Severity'.Substring(4);
In other words: $getVstsBugState.fields.'Microsoft.VSTS.Common.Severity' evaluates to $null, which is why the .Substring() method call fails.
Related
I am trying to automate checking tenant names using the o365.rock website. I want to enter the tenant name and click the button. however I keep getting errors when trying to put the data in the field.
My test code is:-
$site = "https://o365.rocks"
Start-Process "chrome.exe" $site
while ($site.Busy -eq $true){Start-Sleep -seconds 1;}
$input = $site.Document.getElementByID("INPUT");
$input.value = "testing";
I keep getting this error
You cannot call a method on a null-valued expression. At line:4 char:1
$input = $site.Document.getElementByID("INPUT");
I have inspected the elements and the field only has a tagname of "INPUT". The name & ID fields are blank.
Can anyone suggest what I am doing wrong or how else to do this?
You need to give the field ID name because you are using
site.Document.getElementByID
which is looking at the ID part of the field.
Or better use
$tag_name = document.getElementsByTagName("INPUT");
You can check for the availability of an Office 365 tenant name using the following code:
$TenantName = "contoso"
$URI = "https://tenantchecker.easy365manager.com/api/CheckTenantName/" + $TenantName
(Invoke-WebRequest -Uri $URI -Method GET -ContentType 'application/json').Content | ConvertFrom-Json
(source info: https://www.easy365manager.com/tenant-availability-checker/)
So here is my situation. I am running a Jenkins Server with the Generic Webhook Trigger Plugin that is receiving a JSON Webhook from Jira Cloud, and then runs a Powershell script based off of the information in the Webhook to update Jira with the appropriate comments and status transitions. This build worked swimmingly for many months, until the latest update to Jenkins.
Now, when the Jira Webhook fires, the Powershell script runs, and occasionally fails. After some debugging, the reason seems to be at a line of code that had never before posed problems.
One line in the Powershell code does a POST request to Jira API to invoke a Jira status transition on the task in question. In the ideal case, the task begins in the status "To Do", the first POST request fires a transition to "In Progress", then the deploy runs. Once the Deploy is complete, then there is another transition from "In Progress" to "Done".
However, in some cases the tasks do not begin in the To Do status. When the POST request tries to transition a Jira task, say from "In Progress" to "In Progress", there is a 400 response code saying "Bad Request" as the transition is not allowed. This is fine. Previously, the build would receive the 400 error and continue on with the script, which we would like it to continue to do. However, the new behavior is that now, receiving a 400 request fails the entire Jenkins build, and the downstream steps in the script do not run.
We sometimes have need to fire the Webhook while the status is still in In Progress, and these 400 errors are not a big deal for us. What is a big deal is the build failing. How can I stop Jenkins from failing the entire build and stopping my Powershell script short upon one of these cases?
Thanks in advance. I feel like this is a Jenkins Configuration issue I haven't been able to find the answer to anywhere.
JSON Code is too long to add here.
Powershell Script:
param ([string] $JIRA_TOKEN, [int] $BuildNumber)
. "C:\Users\Ameera.Khan\Documents\GitHub\tableau-migration-scripts\workbook_parse.ps1"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 #sets TLS method
Write-Host "Webhook recieved. Success."
$ExitCodePath = "E:\Webhook\TempFiles\ExitCode\ExitCode_$BuildNumber.txt"
$PostDeployIDPath = "E:\Webhook\TempFiles\PostDeployID\PostDeployID_$BuildNumber.txt"
$JiraWebhookPath = "E:\Webhook\TempFiles\Jira_Webhook\$BuildNumber.JSON"
$WorkbooksPath = "E:\Webhook\TempFiles\Workbooks\workbooks_$BuildNumber.txt"
$body = [IO.File]::ReadAllText($JiraWebhookPath) #this reads the temp file that Jenkins wrote containing the JSON Body and stores it in a variable.
$JSON_body = $body | ConvertFrom-Json
$JSON_body.GetType()
# Here we pull out the TCMT plan(s) and the Dashboard Release Ready Ticket type from the JSON.
$TCMT_Plan = $JSON_Body.issue.fields.customfield_10107 #eg, "BCI_MA_MemberIntel.tcmx\nBCI_Medicare_Growth.tcmx"
$dev_workbook_name = $JSON_Body.issue.fields.customfield_10165 #eg, "atrio_memberintel_medicare_memberreporting_v2\nBCI_Medicare_MarketIntelPlanDesign_Dev"
$to_status = $JSON_Body.transition.to_status #should be "Release Ready"
$issue_type = $JSON_Body.issue.fields.issuetype.name #should be "Dashboard Deployment"
# This block validates the parameters and stops the script from running if they're not right.
if (!(($issue_type -eq "Dashboard Deployment") -Xor ($issue_type -eq "Bug")) -or ($to_status -ne "Release Ready") ) {
Write-Host "This transition is not meant to be run."
return
}
if ($dev_workbook_name) {
Write-Host "This Webhook contains a Tableau Workbook name. We will run the Workbook."
}
$credential = $JIRA_TOKEN
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credential))
$encodedCreds = "Basic " + $encodedCreds
$Headers = #{
"X-Atlassian-Token" = "no-check";
"Authorization" = $encodedCreds;
"Content-Type" = "application/json"
"Accept" = "application/json"
}
# We also set some startup variables, like ExitCodeArray and planFiles.
$prod_push = $JSON_Body.issue.fields.subtasks | where { $_.fields.issuetype.name -eq "Deploy" } #finds the Push to Prod subtask
$post_deploy_task = $JSON_Body.issue.fields.subtasks | where { $_.fields.issuetype.name -eq "Post Deployment Testing" } #finds the Post Deploy subtask
$Jira_deploy_subtask_id = $prod_push.key #should be PEP-##### of the Push subtask
$deploy_transition_status = $prod_push.fields.status.name
$ExitCodeArray = New-Object System.Collections.Generic.List[System.Object]
$planFiles = (($TCMT_Plan -split '\r?\n').Trim()) #this line splits the TCMT Plan string into multiple strings at \n.
$workbookFiles = (($dev_workbook_name -split '\r?\n').Trim())
# Save the workbooks within the planFiles into a E:\Webhook\workbooks_$BuildNumber.txt for the next pipeline step, Kinesis CI, to work properly.
workbook_parse -TCMT_Plan $TCMT_Plan -BuildNumber $BuildNumber
Add-Content -Path $WorkbooksPath -Value ($workbookFiles)
$post_deploy_id = $post_deploy_task.key
$post_deploy_transition_status = $post_deploy_task.fields.status.name
$post_deploy_id | Out-File -FilePath $PostDeployIDPath
# Now that we have the subtask, we update the subtask to In Progress by providing the transition id for Open > In Progress in JSON format.
if ($deploy_transition_status -eq "To Do") {
$Uri = "https://carrothealth.atlassian.net/rest/api/2/issue/" + $Jira_deploy_subtask_id + "/transitions"
$RequestBody = #{
"transition" = #{
id = "11"
};
}
# The Invoke-RestMethod method is equivalent to cURL and makes a web request based on the flags and parameters.
Invoke-RestMethod -Method Post -Uri $Uri -H $Headers -Body ($RequestBody | ConvertTo-Json) -Verbose
}
else {
Write-Host "The sub task is done, skipping to next part of deploy. "
}
...until the end of script.
Jenkins Pipeline Script:
pipeline {
agent any
environment {
JIRA_TOKEN = credentials('JIRA_TOKEN')
OAUTH_CLIENT_ID = credentials('OAUTH_CLIENT_ID')
OAUTH_CLIENT_SECRET = credentials('OAUTH_CLIENT_SECRET')
TABLEAU_AUTOMATION_PASSWORD = credentials('TABLEAU_AUTOMATION_PASSWORD')
TABLEAU_AUTOMATION_PASSWORD_KINESIS = credentials('TABLEAU_AUTOMATION_PASSWORD_KINESIS')
}
stages {
stage('Write the Jira Webhook to a file') {
steps {
writeFile(file:"E:/Webhook/TempFiles/Jira_Webhook/${currentBuild.number}.json", text:body)
}
}
stage('Create TCMT Plan in case of Tableau Workbook') {
steps {
powershell(script: "C:/Users/Ameera.Khan/anaconda3/python.exe C:/Users/Ameera.Khan/Documents/GitHub/tableau-migration-scripts/onTheFly.py '${currentBuild.number}'")
}
}
stage('Migrate Content') {
steps {
powershell(script: "C:/Users/Ameera.Khan/Documents/GitHub/tableau-migration-scripts/tcmt_runner_Continuous_Deploy.ps1 -BuildNumber '${currentBuild.number}' -JIRA_TOKEN '${env.JIRA_TOKEN}'")
}
}
stage('Post Deploy Testing') {
steps {
powershell(script: "C:/Users/Ameera.Khan/Documents/GitHub/tableau-migration-scripts/CI_Script.ps1 -BuildNumber '${currentBuild.number}' -JIRA_TOKEN '${env.JIRA_TOKEN}' -OAUTH_CLIENT_ID '${env.OAUTH_CLIENT_ID}' -OAUTH_CLIENT_SECRET '${env.OAUTH_CLIENT_SECRET}' -TABLEAU_AUTOMATION_PASSWORD_KINESIS '${env.TABLEAU_AUTOMATION_PASSWORD_KINESIS}'")
}
}
}
}
Error Log:
VERBOSE: POST https://carrothealth.atlassian.net/rest/api/2/issue/PEP-37938/transitions with -1-byte payload
powershell.exe : Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At C:\Users\Ameera.Khan\AppData\Local\Jenkins\.jenkins\workspace\TableauCD#tmp\durable-2d7da495\powershellWrapper.ps1:3 char:1
+ & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Comm ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Invoke-RestMeth...0) Bad Request.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
At C:\Users\Ameera.Khan\Documents\GitHub\tableau-migration-scripts\tcmt_runner_Continuous_Deploy.ps1:91 char:1
+ Invoke-RestMethod -Method Post -Uri $Uri -H $Headers -Body ($RequestB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
In my scripts, I can avoid a Failed Build through an error with a simple try / catch method.
So try something like this :
# The Invoke-RestMethod method is equivalent to cURL and makes a web request based on the flags and parameters.
try {
Invoke-RestMethod -Method Post -Uri $Uri -H $Headers -Body ($RequestBody | ConvertTo-Json) -Verbose
} catch {
Write-Warning -Message 'Issue already in Progress'
}
If you take a look at the Documentation of PowerShell Pipline Support. You can specify an explicated exit code to mark the build as successful despite errors.
https://www.jenkins.io/blog/2017/07/26/powershell-pipeline/
node {
powershell '''
Write-Error 'Error! Problem Exists Between Keyboard And Chair'
exit 0
'''
}
I have the following script that will deploy an Octopus Deploy release based on the parameters I provide it.
param(
[string] $releaseVersion,
[array] $future
)
foreach($line in Get-Content C:\admin\customers.txt) {
$ErrorActionPreference = "Stop";
# Define working variables
$octopusURL = "http://10.2.2.62:8022/api"
$octopusAPIKey = "API-Key"
$headers = #{ "X-Octopus-ApiKey" = $octopusAPIKey }
$spaceName = "Default"
$projectName = "C9-Deployment"
$environmentName = "LabFarm2"
$tenantNames = $line
$date = get-date -Format yyyy-MM-dd
$expiredate = $(date).AddDays(1).ToString("yyyy-MM-dd")
# Get space id
$spaces = Invoke-WebRequest -Uri "$octopusURL/spaces/all" -Headers $headers -ErrorVariable octoError | ConvertFrom-Json
$space = $spaces | Where-Object { $_.Name -eq $spaceName }
Write-Host "Using Space named $($space.Name) with id $($space.Id)"
# Get project by name
$projects = Invoke-WebRequest -Uri "$octopusURL/projects/all" -Headers $headers -ErrorVariable octoError | ConvertFrom-Json
$project = $projects | Where-Object { $_.Name -eq $projectName }
Write-Host "Using Project named $($project.Name) with id $($project.Id)"
# Create space specific url
$octopusSpaceUrl = "$octopusURL/$($space.Id)"
# Get release by version
$releases = Invoke-RestMethod -Uri "$octopusSpaceUrl/projects/$($project.Id)/releases" -Headers $headers -ErrorVariable octoError
$release = $releases.Items | Where-Object { $_.Version -eq $releaseVersion }
Write-Host "Using Release version $($release.Version) with id $($release.Id)"
# Get environment by name
$environments = Invoke-RestMethod -Uri "$octopusSpaceUrl/environments?partialName=$([uri]::EscapeDataString($environmentName))&skip=0&take=100" -Headers $headers -ErrorVariable octoError
$environment = $environments.Items | Where-Object { $_.Name -eq $environmentName }
Write-Host "Using Environment named $($environment.Name) with id $($environment.Id)"
$tenants = Invoke-WebRequest -Uri "$octopusSpaceUrl/tenants/all" -Headers $headers -ErrorVariable octoError | ConvertFrom-Json
$tenantNames | ForEach-Object {
$name = $_
$tenant = $tenants | Where-Object { $_.Name -eq $name }
if ($future -eq $null) {
write-host "This deployment is for tonight"
$deploymentBody = #{
ReleaseId = $release.Id
EnvironmentId = $environment.Id
TenantId = $tenant.Id
QueueTime = "${date}T23:00:00"
QueueTimeExpiry = "${expiredate}T05:00:00"
} | ConvertTo-Json
}
if ($future -ne $null) {
write-host "This deployment will take place on $future"
#Problem Line 64 below
$expirefuturedate = (get-date $future).Adddays(1).ToString("yyyy-MM-dd")
$deploymentBody = #{
ReleaseId = $release.Id
EnvironmentId = $environment.Id
TenantId = $tenant.Id
QueueTime = "${future}T23:00:00"
#problem line 70 below
QueueTimeExpiry = "${expirefuturedate}T05:00:00"
} | ConvertTo-Json
}
Write-Host "Creating deployment with these values: $deploymentBody"
$deployment = Invoke-WebRequest -Uri $octopusSpaceUrl/deployments -Method POST -Headers $headers -Body $deploymentBody -ErrorVariable octoError
}
}
So the problem is on line 64 and 70 where I try to take add one day to the Future parameter. If I run this with only the ReleaseVersion parameter set it will run fine without issues. But if I add a parameter for future like "-Future 2021-03-11" I get the following error:
PS C:\Users\bbelden.CLOUD9\Documents\powershell\Octopus> .\Deploycustom_parm.ps1 -releaseversion 8.1.2103.193 -future 20
21-03-11
Using Space named Default with id Spaces-1
Using Project named C9-Deployment with id Projects-101
Using Release version 8.1.2103.193 with id Releases-12243
Using Environment named LabFarm2 with id Environments-161
This deployment will take place on 2021-03-11
ForEach-Object : Cannot convert 'System.Object[]' to the type 'System.DateTime' required by parameter 'Date'.
Specified method is not supported.
At C:\Users\bbelden.CLOUD9\Documents\powershell\Octopus\Deploycustom_parm.ps1:47 char:16
+ $tenantNames | ForEach-Object {
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [ForEach-Object], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ForEachObjectCommand
Now if I just remove the line 64 completely and manually set a time date stamp in line 70 like the following:
if ($future -ne $null) {
write-host "This deployment will take place on $future"
#$expirefuturedate = (get-date $future).Adddays(1).ToString("yyyy-MM-dd")
$deploymentBody = #{
ReleaseId = $release.Id
EnvironmentId = $environment.Id
TenantId = $tenant.Id
QueueTime = "${future}T23:00:00"
QueueTimeExpiry = "2021-03-11T05:00:00"
} | ConvertTo-Json
}
It will work fine.
So I am not really sure what I am missing here. Please let me know if there is something I am doing wrong. I believe it has to do with the Array, because if I comment that line out the issue will go away, but I need a way to transform the $future variable to adding one day to it.
Thanks
This should explain your error:
PS /home/> $future=[array]'2021-03-11'
PS /home/> (get-date $future).Adddays(1).ToString("yyyy-MM-dd")
Get-Date: Cannot convert 'System.Object[]' to the type 'System.DateTime' required by parameter 'Date'. Specified method is not supported.
PS /home/> $future=[datetime]'2021-03-11'
PS /home/> (get-date $future).Adddays(1).ToString("yyyy-MM-dd")
2021-03-12
I want to change SSRS data source credential retrieval from using the following credentials to without any credentials with powershell and script fails.
I want to change value 'Store' to 'None' according to this article:
https://learn.microsoft.com/en-us/dotnet/api/reportservice2010.credentialretrievalenum?view=sqlserver-2016#ReportService2010_CredentialRetrievalEnum_None
This is my code:
$uri ='http://ServerName/ReportServer/ReportService2010.asmx?wsdl'
$reporting = New-WebServiceProxy -uri $uri -UseDefaultCredential -namespace "ReportingWebService"
$DataSources = $reporting.ListChildren('/', $true) | Where-Object {$_.Name -eq "DataSourceName"}
foreach($Object in $DataSources) {
$dataSource =$reporting.GetDataSourceContents($Object.path)
#$dataSource.CredentialRetrieval="None"
$dataSource.CredentialRetrieval=[ReportingWebService.CredentialRetrievalEnum]::None
$reporting.SetDataSourceContents($Object.path,$dataSource)
}
This is the error:
Exception calling "SetDataSourceContents" with "2" argument(s): "The combination of values for the fields UserName and CredentialRetrieval are not valid. --->
Microsoft.ReportingServices.Diagnostics.Utilities.InvalidElementCombinationException: The combination of values for the fields UserName and CredentialRetrieval are not valid."
At line:13 char:4
+ $reporting.SetDataSourceContents($Object.path,$dataSource)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SoapException
The issue was that i actually did not change existent credential retrieval settings 'Store' with required Username parameter.
To resolve it i should create new data source definition with new credential retrieval settings and apply it to my data source:
$uri ='http://servername/ReportServer/ReportService2010.asmx?wsdl'
$reporting = New-WebServiceProxy -uri $uri -UseDefaultCredential
$type=$reporting.GetType().Namespace
$DataSources = $reporting.ListChildren('/', $true) | Where-Object {$_.Name -eq "Data source name"}
foreach($Object in $DataSources) {
$dataSource =$reporting.GetDataSourceContents($Object.path)
$dataSourceDefinitionType = ($type + '.DataSourceDefinition');
$dataSourceDefinition = New-Object ($dataSourceDefinitionType);
$dataSourceDefinition.Extension = $dataSource.Extension; #get data from existent data source definition
$dataSourceDefinition.ConnectString = $dataSource.ConnectString #get data from existent data source definition
$credentialRetrievalDataType = ($type + '.CredentialRetrievalEnum');
$credentialRetrieval = new-object ($credentialRetrievalDataType);
$credentialRetrieval.value__ = 3;
$dataSourceDefinition.CredentialRetrieval = $credentialRetrieval;
$dataSourceDefinition.WindowsCredentials = $dataSource.WindowsCredentials; #get data from existent data source definition
$dataSourceDefinition.Enabled = $dataSource.Enabled; #get data from existent data source definition
$dataSourceDefinition.EnabledSpecified = $dataSource.EnabledSpecified; #get data from existent data source definition
$reporting.SetDataSourceContents($Object.path,$dataSourceDefinition)
}
Attempting to Get List Items from SharePoint using PowerShell.
I used the example from here Windows PowerShell Blog, modified it to use with my site. Now I get the following error:
Exception calling "GetListItems" with "7" argument(s): "Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown."
At line:30 char:1
+ $list = $service.GetListItems($listName, "", $query, $viewFields, $rowLimit, $qu ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SoapException
Script I am using:
# The uri refers to the path of the service description, e.g. the .asmx page
$uri = "http://SITE/sites/DefaultCollection/Engineering/Subsite%20(UK)/_vti_bin/lists.asmx"
# Create the service
$service = New-WebServiceProxy -Uri $uri -Namespace SpWs -UseDefaultCredential
# The name of the list
$listName = "Test1"
# Create xml query to retrieve list.
$xmlDoc = new-object System.Xml.XmlDocument
$query = $xmlDoc.CreateElement("Query")
$viewFields = $xmlDoc.CreateElement("ViewFields")
$queryOptions = $xmlDoc.CreateElement("QueryOptions")
$query.set_InnerXml("FieldRef Name='Text1'")
$rowLimit = "10"
$list = $null
$service = $null
try
{
$service = New-WebServiceProxy -Uri $uri -Namespace SpWs -UseDefaultCredential
}
catch
{
Write-Error $_ -ErrorAction:'SilentlyContinue'
}
$list = $service.GetListItems($listName, "", $query, $viewFields, $rowLimit, $queryOptions, "")
if($service -ne $null)
{
try
{
$list = $service.GetListItems($listName, "", $query, $viewFields, $rowLimit, $queryOptions, "")
}
catch
{
Write-Error $_ -ErrorAction:'SilentlyContinue'
}
}
Anyone tried this before? How can I resolve this issue?
Here's the solution worked for me..
Add "?WSDL" to the end of $uri string
$uri = "http://SITE/sites/DefaultCollection/Engineering/Subsite%20(UK)/_vti_bin/lists.asmx?WSDL"
According to this link:To return a service description of a Web service that was created by using ASP.NET, append "?WSDL" to the URL of the Web service (for example, http://www.ss64.com/MyWebService.asmx?WSDL)
The line it is throwing the error at is:
$list = $service.GetListItems($listName, "", $query, $viewFields, $rowLimit, $queryOptions, "")
That line is not caught, but here is a similar issue throwing the same error. If you want to try and get a better exception, wrap the line in another try catch:
try{
$list = $service.GetListItems($listName, "", $query, $viewFields, $rowLimit, $queryOptions, "")
}
catch{
[System.Exception]
write-host ($_.Exception).Message
}
Please make sure to add "?WSDL" to your URI which is why the code breaks. Pretends like it doesn't know the definition of the function (atleast I guess)...
Like the one below. I was surprised to see this made my code work. Weird..
$uri = "http://<>/sites/DefaultCollection/Engineering/Subsite%20(UK)/_vti_bin/lists.asmx?WSDL"