Remove #{} from output and place in command - powershell

I am trying to figure out how to remove the #{} from the output of the $list coming from the CSV file.
I am trying to run the Command "Complete-DomainJoin -Identity $line -DagNumber 023" for each line inside the CSV file
#Complete-DomainJoin (MultipleObjects)
$csv = Import-Csv C:\Temp\DEPTComputers023DEPTComputers023.csv
foreach ($line in $csv) {
Complete-DomainJoin -Identity $line -DagNumber 023
}
When I run this powershell script it errors out because its placing the line item from the CSV into the command as #{xxxx}, from reading around it seems the common way to fix the issue is by adding -ExpandProperty variable but I have not found where to place it or I am not understanding how to implement it correctly.

If everything is in the first column with no header row, then you can try this:
# Name the first column
$csv = Import-Csv C:\Temp\DEPTComputers023DEPTComputers023.csv -Header 'ComputerName'
foreach ($row in $csv) {
# use the ComputerName property
Complete-DomainJoin -Identity $row.ComputerName -DagNumber 023
}
If there aren't any commas in the file at all, then just replace Import-Csv with Get-Content
the #{property=value} syntax means that your object has sub-properties, instead of being a single string

Related

powershell use CSV to create variables

I am a total novice when it comes to powershell. I would like to create a little script to save me a lot of time and after a little research, I am sure it can be achieved using Import-CSV command.
Basically I need to run a command on multiple PC's but the variable is different for each command. I wish to pull that variable from a comparision in a CSV file. So find current Hostname, then use that hostname to find the corresponding asset number in the CSV and then use that asset number as a variable in the final comamnd.
Looking at other examples on here, I have this so far:
$Asset = #()
$Host = #()
Import-Csv -Path "C:\hostnametoasset.csv" |`
ForEach-Object {
$Asset += $_.Asset
$Host += $_.Host
}
$Hostname = (Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
if ($Host -contains $Hostname)
{
C:\BiosConfigUtility64.exe /setvalue:"Asset Tracking Number","$Asset"
}
Section of the CSV:
Asset,Host
10756,PCD001
10324,PCD002
10620,PCD003
Any help would be greatly appreciated.
Couple of different points...
Importing a CSV results in an array of objects that you can filter on.
$Lines = Import-Csv -Path "C:\hostnametoasset.csv"
$Line = $Lines | ?{$_.host -match $ENV:COMPUTERNAME}
You can then use the filter results directly by accessing the member you need.
C:\BiosConfigUtility64.exe /setvalue:"Asset Tracking Number","$($Line.Asset)"
NOTE: I cannot test this directly right now so hopefully I got the syntax right.

Powershell Adjusting Column Values across multiple text files

New to Powershell and looking for some help. I have multiple xyz files that are currently displaying a z value with positive up and I need to make all the values negative (or z-positive down). So far my best attempt has been to try to cobble together what I know from other lines of code, but I'm still far from a solution.
$data = Get-ChildItem "C:\Users\dwilson\Desktop\test" -Recurse |
foreach ($item in $data) {$item.'Col 3' = 0 - $item.'Col 3'}
Any help would be greatly appreciated!
Somewhat of an aside, but you're using mixed syntax here.
foreach ($i in $set) { ... }
This is the Foreach statement. It does not accept input from the pipeline, nor will it automatically send output down the pipeline. See also Get-Help about_Foreach.
Get-ChildItem | ForEach-Object { ... }
This is the ForEach-Object command. It accepts input from the pipeline and sends output down the pipeline. Critically, this command also has a default alias of foreach. See also Get-Help ForEach-Object.
The help for the Foreach statement explains how PowerShell decides what foreach means (emphasis mine):
When Foreach appears in a command pipeline, PowerShell uses the foreach alias, which calls the ForEach-Object command. When you use the foreach alias in a command pipeline, you do not include the ($<item> in $<collection>) syntax as you do with the Foreach statement. This is because the prior command in the pipeline provides this information.
Using the looping over the files returned by Get-ChildItem you can import each with Import-CSV using the -Header parameter to assign the property name for each column. Then we can update the information for that property then export it. Using the ConvertTo-CSV cmdlet and then using Select-Object -Skip 1 we can drop the header off the CSV before exporting it.
$Files = Get-ChildItem "C:\Users\dwilson\Desktop\test" -Recurse
foreach ($File in $Files) {
$Data = Import-CSV $File -Header 'Col1','Col2','Col3'
$newData = ForEach ($Row in $Data) {
$Row.'Col3' = 0 - $Row.'Col3'
$Row
}
$newData |
Convertto-CSV -NoTypeInformation |
Select-Object -Skip 1 |
Out-File "$($File.Fullname).new)"
}

Powershell Import-csv with return character

I tried the following to turn a text file into a document by leveraging import-csv where each item in the original document was a new line
Sample file.txt
James Cameron
Kirk Cobain
Linda Johnson
Code:
$array = import-csv file.txt | ConvertFrom-Csv -Delim `r
foreach ($Data in $array)
{
if (sls $Data Master.txt -quiet)
{Add-Content file.txt $Data}
}
It never created the document
Import-Csv takes a CSV and outputs PSCustomObjects. It's intended for when the file has a header row, and it reads that as the properties of the objects. e.g.
FirstName,LastName
James,Cameron
Kirk,Cobain
# ->
#{FirstName='James';LastName='Cameron'}
#{FirstName='Kirk';LastName='Cobain'}
etc.
If your file has no header row, it will take the first row and then ruin everything else afterwards. You need to provide the -Header 'h1','h2',... parameter to fix that. So you could use -Header Name, but your data only has one property, so there's not much benefit.
ConvertFrom-Csv is intended to do the same thing, but from CSV data in a variable instead of a file. They don't chain together usefully. It will try, but what you end up with is...
A single object, with a property called '#{James=Kirk}' and a value of '#{James=Linda}', where 'James' was taken from line 1 as a column header, and the weird syntax is from forcing those objects through a second conversion.
It's not at all clear why you are reading in from file.txt and adding to file.txt. But since you don't have a CSV, there's no benefit from using the CSV cmdlets.
$lines = Get-Content file.txt
$master = Get-Content master.txt
foreach ($line in $lines)
{
if ($master -contains $line)
{
Add-Content file2.txt $line
}
}
or just
gc file.txt |? { sls $_ master.txt -quiet } | set-content file2.txt
Auto-generated PS help links from my codeblock (if available):
gc is an alias for Get-Content (in module Microsoft.PowerShell.Management)
? is an alias for Where-Object
sls is an alias for Select-String (in module Microsoft.PowerShell.Utility)
Set-Content (in module Microsoft.PowerShell.Management)

Removing a single line from CSV

I have a CSV with several rows and two columns: "Name" and "Information".
I'm looping through the CSV and checking each line for a condition, if the condition is met I'd like to remove the line:
for ($i=0; $i -le $CSV.length; $i++)
{
if ($CSV.name == "Fred")
{
#remove $CSV[$i] -- that one line; both "Name" and "Information"
}
}
I've seen solutions that use Get-Content or Import-Csv and temporary file(s) but I haven't wrapped my head around it and figure there must be an easier way.
Regardless, any help is appreciated!
I would read the CSV using the Import-CSV cmdlet and use the Where-Object cmdlet to filter the entries. Finally, write the CSV back using the Export-CSV cmdlet:
$csv = import-csv 'YourPath.csv'
$csv | Where Name -ne 'Fred' | Export-Csv 'YourPath.csv' -NoTypeInformation

Prevent Powershell ForEach from Adding Superfluous Quotes

I have a colon-delimited CSV like so,
Mailbox:Users
AcmeCorp:("jsmith","trex")
XyzCorp:("sjobs","bfranklin")
It is then added to a variable:
$file = import-csv file.csv -delimiter :
Now, I work with it:
foreach ($record in $file) {
$record.Users | % { get-aduser $_ }
}
write-host in the foreach loop reports $record.Users is ("jsmith","trex")
However, get-aduser (or other cmdlets) complains that it cannot find an object with identity '("jsmith","trex")'.
How do you prevent foreach from adding single quotes to parameter?
I've already tried Users like "sjobs","bfranklin" but import-csv strips the double quotes off of sjobs
Or better, how do you pass a list of users to foreach?
PowerShell version 4
The quotes are not being added by PS. They are right there in your file. Here is a snippet to give you a start in the right direction:
$file = Import-csv file.csv -delimiter ':'
foreach($row in $file){
foreach($user in $row.Users.split(',')){
Get-ADUser ($user.replace('(','').Replace('"','').replace(')',''))
}
}
I think the issue here is that you think that you are importing an array of strings as the value of Users, but you in fact are just importing a single string. There are a couple of options here, using the split method as you have already discovered:
$file = import-csv file.csv -delimiter ':'
ForEach($Record in $File){
$Record.Users.Trim('()').Split(',') | ForEach{
Get-ADUser $_.Trim('"')
}
}
So the $Record.Users.Trim('()') removes the parenthesis from the string. Then it uses .Split(',') to split the string into an array of strings. Then it passes that to an inner ForEach loop when gets the ADUser from each string, after removing the quotes from around it (with .Trim('"')).
Alternatively you could have one user per line, so your CSV would appear like:
Mailbox:User
AcmeCorp:jsmith
AcmeCorp:trex
XyzCorp:sjobs
XyzCorp:bfranklin
Then after importing the CSV you could just group by the mailbox if needed, say, to add users per mailbox or something:
$File = Import-CSV C:\Path\To\File.csv -delimiter ':'
$MBGroups = $File | Group Mailbox
ForEach($Record in $MBGroups){
$Mailbox = $Record.Name
$Users = $Record.Group | ForEach{Get-ADUser $_.User}
$Users | ForEach{Set-ADUser -mail ($_.samaccountname+"#"+$Mailbox+".com")}
}