I have the following code, which is a bit more than minimally functional, but I hope it's still understandable.
$data = 'PATH TO SOME FILE OR FOLDER'
$rule = #{
property = 'size'
operator = 'lt'
value = '1000gb'
note = $null
logOnForgo = $false
}
$ruleOperationArguments = #{
operator = $rule.operator
operand1 = $Null # always the current state to be tested, and depends on specific rule
logString1 = $rule.property
operand2 = $rule.value
logString2 = $rule.value # sometimes modified by rule
note = $rule.note
logOnForgo = $rule.logOnForgo
}
if (($item = Get-Item $data).PSIsContainer) {
$actualSize = 0
foreach ($childItem in (Get-ChildItem $item -recurse | Where {-not $_.PSIsContainer} | ForEach-Object {$_.FullName})) {
$actualSize += (Get-Item $childItem).length
}
} else {
$actualSize = $item.length
}
$ruleOperationArguments.operand1 = $actualSize
if ($actualSize -gt 1TB) {
$actualSizeString = "$([math]::Round(($actualSize/1TB),2))TB"
} elseif ($actualSize -gt 1GB) {
$actualSizeString = "$([math]::Round(($actualSize/1GB),2))GB"
} elseif ($actualSize -gt 1mb) {
$actualSizeString = "$([math]::Round(($actualSize/1MB),2))MB"
} elseif ($actualSize -gt 1kb) {
$actualSizeString = "$([math]::Round(($actualSize/1KB),2))KB"
} else {
$actualSizeString = "$([math]::Round(($actualSize),2))Bytes"
}
$ruleOperationArguments.logString1 = "$($ruleOperationArguments.logString1) ($actualSizeString)"
# test size
switch ($interval[0].Groups['unit'].Value) {
kb {$ruleOperationArguments.operand2 = [System.Int64]($interval[0].Groups['number'].Value) * 1kb}
mb {$ruleOperationArguments.operand2 = [System.Int64]($interval[0].Groups['number'].Value) * 1mb}
gb {$ruleOperationArguments.operand2 = [System.Int64]($interval[0].Groups['number'].Value) * 1gb}
tb {$ruleOperationArguments.operand2 = [System.Int64]($interval[0].Groups['number'].Value) * 1tb}
}
$ruleOperationArguments
I am getting a very odd error
Cannot index into a null array. At line:39 char:41
that line is
$ruleOperationArguments.logString1 = "$($ruleOperationArguments.logString1) ($actualSizeString)"
But here is the odd thing. the code WORKS. The actual final value of $ruleOperationArguments.logString1 IS updated to include the actual size data.
I have also tried not modifying the hash table value by appending to itself, instead using, same result.
$ruleOperationArguments.logString1 = "$($rule.property) ($actualSizeString)"
It's not actually related to the data being put into the hash table, because
$ruleOperationArguments.logString1 = "WTAF?"
also throws the error. What is different about the logStrings that causes problems, while the operands are working without issue? I even tried running the code in a new instance of the ISE, thinking I could have issues with persisting variables. Nope, same issue. I am utterly stumped. I should not that I got a lot fo hits searching on 'Cannot index into a null array' but they all reference actual situations where an array is empty. But $ruleOperationArguments sent to the console will show that the only part of the hash table that is empty is the note key that I am not even using, and operand1 that get's populated before the error condition. Both logStrings have values, and I can successfully update them, but this false error still gets thrown.
EDIT: To minimize the complexity I tried this
$rule = #{
property = 'size'
operator = 'lt'
value = '1000gb'
note = $null
logOnForgo = $false
}
$ruleOperationArguments = #{
operator = $rule.operator
operand1 = $Null
logString1 = $rule.property
operand2 = $rule.value
logString2 = $rule.value
}
$ruleOperationArguments
$ruleOperationArguments.logString1 = "$($ruleOperationArguments.logString1) changed"
$ruleOperationArguments
And thworks with no errors. So something is the rest fo the code is causing the issue, but I still have no clue what.
I think somewhere, you swizzled the line mentioned in the error. When I run the original sample locally, up to the line mentioned in the error and question, the error doesn't occur, and there is nothing that should cause this above. However, running the whole thing results in the same error... but for the switch statement condition. Ignore the line number mismatch here:
Cannot index into a null array.
At line:1 char:9
+ switch ($interval[0].Groups['unit'].Value) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Looking more closely at this, $interval isn't defined anywhere. You need to initialize this as an Array, List, or some other type of collection.
Below is the result of an API call via Invoke-Restmethod
And output of $test.result.organizationContext is as follows
How can I add an line item to this "organizationContext" object with values for the different attributes like " name", "id" ?
If we assume that you already have the values you want to add defined in variables, you can create a new custom object and then effectively, yet inefficiently, add it to the array.
$newOrganizationContext = [pscustomobject]#{
classificationId = $classificationId
group = $group
id = $id
isGroupSeparator = $isGroupSeparator
name = $name
objectId = $objectId
path = $path
subClass = $subClass
synchronized = $synchronized
type = $type
}
$test.result.organizationContext += $newOrganizationContext
I want to get the renderings (presentation details) of each items.
I have tried using Get-Rendering, but it doesn't work.
$criteria = #(
#{ Filter = "Equals"; Field = "_template"; Value = "{9A43A639-4209-49B9-8024-766A9E1AB03E}"; },
#{ Filter = "DescendantOf"; Value = (Get-Item "master:/content/"); }
)
$props = #{
Index = "sitecore_master_index"
Criteria = $criteria
}
Find-Item #props | Get-Rendering -FinalLayout
It throws the following error:
The input object cannot be bound to any parameters for the command
either because the command does not take pipeline input or the input
and its properties do not match any of the parameters that take
pipeline input.
What am I missing?
$ReleaseBody = #{
Id = $Project.Id
ProjectId = $Project.Id
ChannelId = $Channels.Items.Id
Version = $VERSION
SelectedPackages = #( #{
StepName = $DeploymentProcess.Steps.Name[0]
Version = $dt.Items.Version
})
} | ConvertTo-Json
I am querying an API that returns one or more StepName via $DeploymentProcess, I want to always select the first for my POST. The above works fine if there are multiple steps but not if there is only one. Thoughts?
SCENARIO:
In my script, I create an object, add the common info, and then updated the sub info for each object in a loop and add that object to an array of objects.
My verbose shows that the values are correct in the object added to the array (reporting the last item in the array), but Export-Csv repeats the last object values.
I am able to resolve this if I create a new object each time. Reusing the same object repeats the last value, even though I can see it correct when I select * on the objects in the array. There must be something about the array object, such as a guid that is duplicated for the same object.
PowerShell 5.1 verified on Windows 7, Windows 2008R2, Windows 2010R2
SOLUTION:
Do not reuse an object when adding it to an array of objects.
OUTPUT:
#TYPE MyGpoSetting
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName","SubState","SubValue","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
SCRIPT:
Add-Type -TypeDefinition #"
public struct MyGpoSetting
{
public string SetName;
public string SetCategory;
public string SetType;
public string SetState;
public string SetValue;
public string SetData;
public string SetNote;
public string SubName;
public string SubState;
public string SubValue;
public string GpoDomain;
public string GpoName;
public string GpoLinks;
public string GpoGuid;
}
"#
$aoMyGpoSetting = #();
$oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName1';
$oMyGpoSetting.SubState = 'SubState1';
$oMyGpoSetting.SubValue = 'SubValue1';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName2';
$oMyGpoSetting.SubState = 'SubState2';
$oMyGpoSetting.SubValue = 'SubValue2';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName3';
$oMyGpoSetting.SubState = 'SubState3';
$oMyGpoSetting.SubValue = 'SubValue3';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
$aoMyGpoSetting | Export-Csv -Path 'c:\temp\export.csv' -Encoding 'ASCII';
This is working as expected. Adding the object to the array (+=) doesn't copy the object, but instead adds a reference/pointer to it in the next 'slot'. So in effect you are adding three references to the same object. It's like having 3 entries in your phonebook for your best friend:
John Smith - 01234 5678
Jonnie - 01234 5678
Smith, John - 01234 5678
Whichever one you call, gets you through to the exact same person.
Similarly, each time PowerShell displays an object from your array, it is actually going back to the same source object and showing it to you. That is why all of them have the same properties as the last one you added - they are in fact all that same one.
As you've discovered, creating a new object each time is the way to proceed.