Nuisance
Nuisance

Reputation: 47

How do i overwrite a field in a csv file with PowerShell?

CSV sample:

CSV Sample

I have the below code, where I would like to overwrite the current value in the PreviousGroup field. I know that -append adds to the end of the column, but that's not what I want to do.

$UserGroup = read-host "Enter Group Name"
$csvFile = Import-Csv "C:\HomeFolder\Locations.csv"
if ([string]::IsNullOrEmpty($PreviousGroup)) {$PreviousGroup = ""}
else {$PreviousGroup = $csvFile | Select-Object $csvFile.PreviousGroup -Verbose}

$csvFile.PreviousGroup = $UserGroup
$csvFile | Export-Csv

Secondly, is it possible to link Dom*_Groups in the below code to the list on the CSV?

param([Parameter(Mandatory = $false)]
        [ValidateSet(*"list from csv"*)] [string]$Dom1_Groups)
param([Parameter(Mandatory = $false)]
        [ValidateSet(*"list from csv"*)] [string]$Dom2_Groups)

Upvotes: 1

Views: 684

Answers (1)

mklement0
mklement0

Reputation: 440307

$csvFile, as returned from Import-Csv, is an array of [pscustomobject] instances.

Therefore, assigning to the .PreviousGroup property of $csvFile in an attempt to assign to its elements' .PreviousGroup properties will not work: while it's understandable to attempt this, given that getting the elements' property values this way does work, via member-access enumeration, member-access enumeration by design only works for getting, not also for setting property values.

The simplest solution is to use the .ForEach() array method:

# Set the .PreviousGroup property of all elements of array $csvFile
# to the value of $UserGroup.
$csvFile.ForEach('PreviousGroup', $UserGroup)

Caveat: As of PowerShell 7.1, the above method of assigning property values unexpectedly fails if the input object happens to be a scalar (single object), which can happen if the CSV file happens to contain just one data row; see GitHub issue #14527.
An - inefficient - workaround is to use @(), the array-subexpression operator:
@($csvFile).ForEach('PreviousGroup', $UserGroup)
or to use a script block ({ ... }):
$csvFile.ForEach({ $_.PreviousGroup = $UserGroup })

Upvotes: 1

Related Questions