My script is supposed to get content of an exported XML file, connect to SharePoint (2010) and create folder/files according to the XML file content.
The XML file is build like this:
<?xml version="1.0" encoding="UTF-8"?>
<Domain name = "DomainName">
<Environments>
<Environment1 name = "Env1">
<Applications>
<Application1 name = "App1">
<Jobs>
<Job1 name = "Job1">
</Job1>
<Job2 name = "Job2">
</Job2>
<Job3 name = "Job3">
</Job3>
</Jobs>
</Application1>
<Application2 name = "App2">
</Application2>
<Application2>
</Application2>
</Applications>
</Environment1>
<Environment2 name = "Env2">
... content ...
</Environment2>
<Environment3>
... content ...
</Environment3>
<Environment4>
... content ...
</Environment4>
</Environments
<ObjectInstructions>
<ObjectInstruction objectName="ObjName1" instructionName="App">
<ObjectInstruction objectName="ObjName2" instructionName="App">
<ObjectInstruction objectName="ObjName3" instructionName="Job">
<ObjectInstruction objectName="ObjName4" instructionName="Job">
<ObjectInstruction objectName="ObjName5" instructionName="ForeWriter">
<ObjectInstruction objectName="ObjName6" instructionName="MySite">
</ObjectInstructions>
</Domain>
So folders and files have to be the Environment/Application or Job names. I managed to do this part. In fact almost everything works except one thing.
When my script encounters an Application or a Job with only one field, their name is not taken, the script skips it. It's because the variable is supposed to be an array, but in this particular case it is a String.
Part of the code that don't work well:
$CountEnv = $script:XmlContent.domain.Environments.Environment.Count # nb total of Environment
for ($e = 0; $e -lt $CountEnv; $e++) {
$Envname = $script:XmlContent.domain.Environments.Environment[$e].name # Get the name of the Environment n°$e
foreach ($Envelement in $Envname) {
try { # Creation folder Environment
$ParentEnvFolder = $script:web.GetFolderByServerRelativeUrl($script:Library)
$EnvFolder = $ParentEnvFolder.Folders.Add($Envelement)
Write-Host " * Environment Folder : $Envelement created * " -ForegroundColor Magenta -BackgroundColor Black
$compteurEnv++
$script:ctx.Load($ParentEnvFolder)
$script:ctx.ExecuteQuery()
} catch {
Write-Host " Error on Folder $Envelement creation "
}
### LIGNES THAT CAUSE ME TROUBLES ###
$CountApp = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application.Count # nb total of Application in the actual Environment
for ($a = 0; $a -lt $CountApp; $a++) {
$Appname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application[$a].name # Get the name of the Application n°$a in the actual Environment
if ($Appname -and $Appname.Length -eq 1) {
$Appname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application.name
}
Write-Host " appname :"$Appname
### END LIGNES THAT CAUSE ME TROUBLES ###
foreach ($Appelement in $Appname) {
$cnA = Check-Names $Appelement # Verification that the Env / App or Job name don't contains specific words, here the cnA is for Application
if ($cnA -eq 1) {
$ciA = Check-InstructionsApp $Envelement $Appelement # Verification that the Application name is present in the list of the objectName and that instructionName is App in ObjectIntruction
if ($ciA -eq 1) {
$GetAppfile = $script:web.GetFileByServerRelativeUrl("/$LastPart_ctxUrl/$script:Library/$Envelement/$Appelement.aspx")
$AfileExist = $false
try { # Verification file Appplication.aspx exist
$script:ctx.Load($GetAppfile)
$script:ctx.ExecuteQuery()
$AfileExist = $GetAppfile.Exists
} catch { }
if ($AfileExist) {
Write-Host " File $Appelement.aspx Already exist"
} else {
try { # Creation file Application.aspx
$AppFile = $ParentEnvFolder.Files.AddTemplateFile("/$LastPart_ctxUrl/$script:Library/$Envelement/"+"$Appelement.aspx",1)
$script:ctx.Load($AppFile)
$script:ctx.ExecuteQuery()
Write-Host " ** Application file : $Appelement created ** " -ForegroundColor Green -BackgroundColor Black
$compteurAppfile++
} catch {
Write-Host " Error, file creation $Appelement failed" -ForegroundColor Red -BackgroundColor Black
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
}
}
}
}
### LIGNES THAT CAUSE ME TROUBLES ###
$CountJob = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application[$a].Jobs.Job.Count # nb total of Job in the actual Application
for ($j = 0; $j -lt $CountJob; $j++) {
$Jobname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application[$a].Jobs.Job[$j].name # Get the name of the job n°$j in the actual Application
if ($Jobname -and $Jobname.Length -eq 1) {
$Jobname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application[$a].Jobs.Job.name
}
Write-Host " jobname : "$Jobname
###END LIGNES THAT CAUSE ME TROUBLES ###
foreach ($Jobelement in $Jobname) {
$cnJ = Check-Names $Appelement $Jobelement # Verification that the Env / App or Job name don't contains specific words, here the cnJ is for Job
if ($cnJ -eq 2) {
$ciJ = Check-InstructionsJob $Envelement $Appelement $Jobelement # Verification that the Job name is present in the list of the objectName and that instructionName is Job in ObjectIntruction
if ($ciJ -eq 1) {
try { # Creation Folder Application
$ParentAppFolder = $script:web.GetFolderByServerRelativeUrl("$script:Library/$Envelement/")
$AppFolder = $ParentAppFolder.Folders.Add("$Appelement")
$compteurAppFolder++
Write-Host " ** Application Folder $Appelement created ** " -ForegroundColor Cyan -BackgroundColor Black
$script:ctx.Load($ParentAppFolder)
$script:ctx.ExecuteQuery()
} catch {
Write-Host " Error on Application :$Appelement folder creation "
}
$GetJobfile = $web.GetFileByServerRelativeUrl("/$LastPart_ctxUrl/$script:Library/$Envelement/$Appelement/$Jobelement.aspx")
$JfileExist = $false
try { # Verification file Job.aspx already exist
$script:ctx.Load($GetJobfile)
$script:ctx.ExecuteQuery()
$JfileExist = $GetJobfile.Exists
} catch { }
if ($JfileExist) {
Write-Host " File $Jobelement.aspx Already exist"
}
try { # Creation file Job.aspx
$JobFile = $ParentAppFolder.Files.AddTemplateFile("/$LastPart_ctxUrl/$script:Library/$Envelement/$Appelement/"+"$Jobelement.aspx",1)
$script:ctx.Load($JobFile)
$script:ctx.ExecuteQuery()
Write-Host " *** Job file : $Jobelement created *** " -ForegroundColor Yellow -BackgroundColor Black
$compteurJob++
} catch {
Write-Host " Error, file creation $Jobelement failed" -ForegroundColor Red -BackgroundColor Black
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
}
}
}
}
}
}
}
}
}
$compteurApp = $compteurAppfile + $compteurAppFolder
Write-Host "`nNumber of environment created: $compteurEnv," "Number of applications created: $compteurApp" " with $compteurAppFolder App folder and $compteurAppfile App file," "Number of job created: $compteurJob"
Let me know if I can provide any information that might be useful to you.
Edit : Thank you Ansgar for the link you provided, unfortunately I'm not in the same case.
By doing research I now have an idea where to head toward. As I said in the comment under yours, it's a problem of method. The ... .Aplications.Application.count
and ....Applications.Application[0].Name
don't exist in the case where there's only one or no values returned. I managed to make it work, but it's a disgusting way of doing it.
This is what changed:
$CountApp = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application.Count
if(!$CountApp)
{
$CountApp = 1
}
for($a = 0; $a -lt $CountApp; $a++)
{
try
{
$Appname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application[$a].name
if(!$Appname)
{
$Appname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application.name
}
}
catch{ }
And before
$CountApp = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application.Count # nb total of Application in the actual Environment
for ($a = 0; $a -lt $CountApp; $a++) {
$Appname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application[$a].name # Get the name of the Application n°$a in the actual Environment
if ($Appname -and $Appname.Length -eq 1) {
$Appname = $script:XmlContent.domain.Environments.Environment[$e].Applications.Application.name
}
So with this modification, now I do create everything but I got an error because I force $CountApp
to 1 even if there's nothing.
I fixed that with the Try{]Catch{}
around $Appname
.