Powershell excel header sorting by alphabet - excel

I have the following code to get the headers in an excel
$inputTable = Import-Excel -Path $inputFile
$sourceTable = $inputTable | Get-Member -MemberType NoteProperty | %{"$($_.Name)"}
However it is sorting by alphabet. I want the headers in the same sequence as in the excel. How should I do it?

try this :
$inputTable | get-Member -force | where Name -eq "psextended" | %{
$_.Definition.replace('psextended', '').replace('{', '').replace('}', '').Trim() -split ',' | %{$_.trim()}
}

Related

Adding string to object emailaddresses

I'm trying to add a string to the emailaddresses objects of an Exchange mailbox.
But when I add the string, it doesn't show anything.
Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,PrimarySmtpAddress, #{Name="EmailAddresses";Expression={($_.EmailAddresses | Where-Object {$_ -clike "*smtp*"} | ForEach-Object {$_ -join '_OLD'})}} | where-object {($_.primarysmtpaddress -like "juan#contoso.com")}
but when I do a replace operation, it shows me the emailaddresses replaced correctly. Why doesn't it add the string but replace it?
Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,PrimarySmtpAddress, #{Name="EmailAddresses";Expression={($_.EmailAddresses | Where-Object {$_ -clike "*smtp*"} | ForEach-Object {$_ -replace "smtp:","Remp:"}) -join "OLD"}} | where-object {($_.primarysmtpaddress -like "juan#contoso.com")}
I have also tried with the concatenation operator, but I get the same result.
thanks in advance.

Powershell, how obtain a csv by column with a pscustomobject or ordered?

Being a beginner in Powershell, I have a problem that I can't solve. I get the average of different CSV files as a string with the following code:
# recovery of the list of csv files present in the folder "folder_1".
$files=(Get-ChildItem -path "C:\folder_1\" -Recurse -Include *.csv)
#loop to read each file and average the variables "PRESS_CELL" and "PRESS_DELTA
foreach($file in $files){
$varTemp = #((Get-Content $file | ConvertFrom-Csv | Measure-Object "PRESS_CELL","PRESS_DELTA" -Average | Export-Csv -Path "C:\folder_1\Alias.csv" -NoTypeInformation -Append))
Write-Host $varTemp
}
#added an increment to sort the data (averages)
$vartemp2 = Import-CSV "C:\folder_1\Alias.csv" | Select *,LINENUMBER | ForEach-Object -Begin { $Line = 1 } {
$_.LineNumber = $Line++
$_
} | Export-CSV "C:\folder_1\Alias2.csv" -NoTypeInformation
Write-Host $vartemp2
# sort data by "property" and by "LINENUMBER"
$vartemp3 = Import-Csv "C:\folder_1\Alias2.csv"
$vartemp3 | % { $_.LINENUMBER = [int]$_.LINENUMBER }
$vartemp3 | Sort-Object -Property #{ Expression = 'Property'; Ascending = $true }, #{ Expression = 'LINENUMBER'; Ascending = $true } |
Format-Table -Property "Average","Property","LINENUMBER"
# groups the values obtained in a table/customobject and export it to csv by column ?
$fields = [ordered]#{
PRESS_CELL = $vartemp3 | ? property -like *PRESS_CELL* | Select -ExpandProperty Average
PRESS_DELTA = $vartemp3 | ? property -like *PRESS_DELTA* |Select -ExpandProperty Average
}
$fields | export-csv C:\1_ICOS_data\Alias4.csv -Append ##DOESN'T WORK
[result][1]
However, I would like to export the result as a CSV table (1 column per result with PRESS_CELL and PRESS_DELTA as headers. When I use the pipeline :
| export-csv C:\temp\alias.csv -Append
I get a result :
With "ordered"
"System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
And with pscustomobject :
System.Object[],"System.Object[]"
Add -NoTypeInformation to export-csv command like that
$fields = [ordered]#{
PRESS_CELL = $vartemp3 | ? property -like *PRESS_CELL* | Select -ExpandProperty Average
PRESS_DELTA = $vartemp3 | ? property -like *PRESS_DELTA* |Select -ExpandProperty Average
}
#Or:
$fields = [pscustomobject]#{
PRESS_CELL = $vartemp3 | ? property -like *PRESS_CELL* | Select -ExpandProperty Average
PRESS_DELTA = $vartemp3 | ? property -like *PRESS_DELTA* |Select -ExpandProperty Average }
$fields |export-csv "c:\fields.csv" -Append -NoTypeInformation

Code to grab file data into PSOObject and sort by LastWriteTime

I am looking to recursively grab a list of recently modified files under two network drives, sort them in descending date order, and make some edits to the CSV file to tidy the list for Excel
I have cobbled the code below from a number of sources (I am a powershell beginner) and it is now doing what I need (i.e. producing a list).
I need help in going a step further, I cannot sort the resultant CSV file by file last write time date, is this because my array is expecting text rather than a numeric field?
I also am returning the domain name as well as the file owner with ((Get-ACL $_.FullName).Owner). I tried using Replace to cut down the string, but had no luck with this approach.
$arr = #()
$days_to_check=$(Get-Date).AddDays(-28)
$items = #(Get-ChildItem '\\ND\dir 1\*.*' -Recurse -ErrorAction SilentlyContinue | where { $_.LastWriteTime -gt $days_to_check})
$items += #(Get-ChildItem '\\ND\dir 1\*.*' -Recurse -ErrorAction SilentlyContinue |
where { $_.LastWriteTime -gt $days_to_check})
$items | Foreach {
$obj = New-Object PSObject -prop $hash
$obj | Add-Member NoteProperty FullName $_.FullName
$obj | Add-Member NoteProperty Directory $_.Directory
$obj | Add-Member NoteProperty Name $_.Name
$obj | Add-Member NoteProperty LastTime $_.LastWriteTime
$obj | Add-Member NoteProperty Owner ((Get-ACL $_.FullName).Owner)
$arr += $obj
}
$arr | Format-List
$arr | Sort-Object -Property LastTime -Descending
$arr | Export-CSV -notypeinformation C:\temp\filenamesFO.csv
CSV file sorted by date field
You did sort your array in the output but that's all you did.
If you want to actually export it that way, you have to assign the sort to $arr
Replace
$arr | Sort-Object -Property LastTime -Descending
with
$arr = $arr | Sort-Object -Property LastTime -Descending
You can remove the Owner domain using the following Replace -replace '(.*\\)(.*)','$2'
Here's a complete example implementing the changes mentionned above.
$arr = new-object -TypeName 'System.Collections.Generic.List[PSObject]'
$days_to_check=$(Get-Date).AddDays(-28)
$items = #(Get-ChildItem '\\ND\dir 1\*.*' -Recurse -ErrorAction SilentlyContinue | where { $_.LastWriteTime -gt $days_to_check})
$items += #(Get-ChildItem '\\ND\dir 1\*.*' -Recurse -ErrorAction SilentlyContinue |
where { $_.LastWriteTime -gt $days_to_check})
Foreach ($item in $items) {
$obj = [PSCustomObject]#{
FullName = $item.FullName
Directory = $item.Directory
Name = $item.Name
LastTime = $item.LastWriteTime
Owner = (Get-ACL $item.FullName).Owner -replace '(.*\\)(.*)','$2'
}
$arr.add($obj)
}
$arr = $arr | Sort-Object -Property LastTime -Descending
#$arr | Format-List
$arr | Export-CSV -notypeinformation C:\temp\filenamesFO.csv
I made some additional changes:
Instead of using an array, I used a List of PSObject. If you have a lot of files, the processing time will be improved in comparison with an array.
I used the PSCustomObject declaration just to show an alternative to all those Add-member. I find it cleaner but it is up to you in the end.

powershell script, text placement in cells in csv file

So, to continue my lovely journey through powershell from here:
Loop for two variables
I have a ps1 that runs a loop for a bunch of transactions and a bunch of nodes and sends them over to a csv file.
$url = "https://someserver/trans="
$transactions = '1','2','3','4' #There are 4 transactions
$nodes = 'node1','node2','node3','node4','node5','node6' #There are 10 nodes
Remove-Item ATM.csv -Force
# So far so good
# Below is what I'd use as a function in bash. No sure what/how to do in PS:
#OUTPUT:
foreach($transaction in $transactions)
{
foreach($node in $nodes)
{
"$transaction;$node" |out-file -Append ATM.csv
curl -k -u user#pass $url$transaction$node | findstr "<value>" | out-file -Append ATM.csv
}
}
Opening the file in excel, I end up with this output under column A:
transaction1;node1 (in the first row, left-most cell)
value1 (from the curl. It's actually a number and it sits in the row right under the first entry)
and so on and so forth for 2,3, and the rest. only the left most column (column A) gets populated.
What I'd like to get is a way to place the values in three columns, such that the csv will look like:
Column A | Column B | Column C
transaction1| node1 | valueX
transaction2| node2 | valueY
and so on. The script or another will have to do this, the end user for this job who'll run the script will not open excel every day and start running macros, he needs the final csv ready from the script.
Whatever shall I do?
Something like this will fix your issues, the only bit that's not included is selecting the value itself from Invoke-WebRequest (curl) as that will change depending on what's returned.
foreach($transaction in $transactions)
{
foreach($node in $nodes)
{
$value = Invoke-WebRequest -Uri $url$transaction$node -UseBasicParsing | Select-Object -Expand Content
Add-Content -Path ATM.csv -Value "$transaction,$node,$value"
}
}
You are currently writing your output in two different lines. One solution could be to use the NoNewLine parameter in the Out-File:
"$transaction;$node" |out-file -Append ATM.csv -nonewline
curl -k -u user#pass $url$transaction$node | findstr "<value>" | out-file -Append ATM.csv
Personally I would create a Powershell Object and create the csv at the end:
$array = #()
foreach($node in $nodes) {
$obj = New-Object psobject
$obj | Add-Member -MemberType NoteProperty -Name 'Transaction' -Value $transaction
$obj | Add-Member -MemberType NoteProperty -Name 'Node' -Value $node
$obj | Add-Member -MemberType NoteProperty -Name 'Value' -Value (curl -k -u user#pass $url$transaction$node | findstr "<value>")
$array += $obj
}

Export-CSV only gets the "Length"

when I try to export to a CSV list, I only get all number for "Length"
.Count property until the split point is reached, then split the CSV array to a new file with a new name that will be used from this point on. What might be the issue?
$RootFolder = Get-Content "c:\DRIVERS\myfile.txt"
foreach ($arrayOfPaths in $RootFolder){
$csv = $arrayofPaths -replace '^\\\\[^\\]+\\([^\\]+)\\([^\\]+).*', 'C:\output\Company_name_${1}_${2}.csv'
$csvIndex = 1
$maxRows = 1000000
$rowsLeft = $maxRows
Get-ChildItem $arrayOfPaths -Recurse | Where-Object {$_.mode -match "d"} | ForEach-Object {
#$csv = $_.FullName -replace '^\\\\[^\\]+\\([^\\]+)\\([^\\]+).*', 'C:\output\Company_name_${1}_${2}.csv'# <- construct CSV path here
$path = $_.FullName
$thisCSV = Get-Acl $path | Select-Object -Expand Access |
Select-Object #{n='Path';e={$path}}, IdentityReference, AccessControlType,
FileSystemRights |
ConvertTo-Csv
if ($thisCSV.count -lt $rowsLeft) {
$thisCSV | Export-Csv $csv -append -noType
$rowsLeft -= $thisCSV.count
} else {
$thisCSV[0..($rowsLeft - 1)] | Export-Csv $csv -append -noType
$csvIndex++
$csv = $csv -replace '\.csv$', "$csvIndex.csv"
if ($thisCSV.count -gt $rowsLeft) {
$thisCSV[$rowsLeft..($thisCSV.count - 1)] | Export-Csv $csv -append -noType
}
$rowsLeft = $maxRows - ($thisCSV.count - $rowsLeft)
}
}
}
Export-CSV is built to take PSCustomObjects as input, not lines of text.
$thisCSV = Get-Acl $path | Select-Object -Expand Access |
Select-Object #{n='Path';e={$path}}, IdentityReference, AccessControlType,
FileSystemRights |
ConvertTo-Csv
The output of this line will be something like:
#TYPE Selected.System.Security.AccessControl.FileSystemAccessRule
"Path","IdentityReference","AccessControlType","FileSystemRights"
"c:\test","BUILTIN\Administrators","Allow","FullControl"
At least three lines, an array of string. What properties does an array of string have?
PS C:\> 'a','b' | Get-Member -MemberType Property
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
Length Property int Length {get;}
Length. The only property you see in the CSV, because Export-CSV is exporting all the properties, and that's the only property.
Fix: Remove | ConvertTo-CSV from the Get-ACL line, leave your custom objects as custom objects and let the export handle converting them.
(This should also fix the counting, because it's not counting 3+ lines of text while trying to export 1+ line of data every time).

Resources