Issue with export-csv no data? - excel

In my report when I remove the export-csv portion the data is presented correctly onscreen, when I add in the export-csv no data is exported but the file is created. Below is my script along with what the data looks like when script is running (modified) of what the data looks like.
#Get all DHCP Servers
$ServerList = (Get-Content -Path "\\termserv\DHCPServers.txt")
foreach ($server in $serverlist)
{
#Get the scopes from each serve
Get-DHCPServerv4Scope -ComputerName $server | select ScopeID |
#Get the lease information for each scope
ForEach-Object {Get-DHCPServerv4Lease -ScopeId $_.ScopeId -ComputerName
$server -AllLeases |
where {$_.AddressState -like "*Reservation"} | Select-Object
$server,ScopeId,IPAddress,HostName,ClientID,AddressState | Export-
Csv "\\termserv\d$\term\User\Reservations1.csv"
}
}
What the data looks like when exported without export-csv
NOPEDH01 :
ScopeId : 000.11.2.3
IPAddress : 111.22.3.444
HostName : NOPE00112233
ClientID : 00-11-22-33-44-55
AddressState : ActiveReservation
NOPEDH01 :
ScopeId : 000.11.2.3
IPAddress : 111.22.3.445
HostName : NOPE0011223344
ClientID : 00-11-22-33-44-56
AddressState : ActiveReservation
Update: Tried that and still nothing, when I run a modified version of the script locally on my DH servers it functions correctly, but I'm looking at almost 100 DH servers in my environment, see below
Get-DHCPServerV4Scope | ForEach {
Get-DHCPServerv4Lease -ScopeID $_.ScopeID -AllLeases | where
{$_.AddressState -like '*Reservation'}
} | Select-Object ScopeId,IPAddress,HostName,ClientID,AddressState | Export-
Csv "\\termserv\d$\term\$($env:COMPUTERNAME)-Reservations1.csv" -
NoTypeInformation

This is a representation of what you are doing:
Foreach ($Server in $ServerList)
{
Foreach ($Scope in $ScopeList)
{
$Data | Export-csv -Path FileName.csv
}
}
In doing so you are exporting data [(Total Servers) x (Total Scopes per server)] times which is a lot of I/O operations. It is just a logistics issue. You could collect the entire information into a table object before exporting. But that decision is up to you and your particular business needs.
The real issue, however, is that you are doing the export into the same file which essentially over writes whatever you have written before without telling it not to. So only the last export remains which I suspect is somehow blank.
Try using the -Append switch when you export.
$Data | Export-csv -Path FileName.csv -NoTypeInformation -Append
Also I noticed you are using $server variable in the select-object cmdlet where you should only be using the object's property names and not variable names. I do not know if that returns anything as the cmdlet would not know what to do with it, which could also be contributing to the problem.

According to your code you are using Export-Csv within a foreach-object. Generally Export-csv creates a csv file with new data. If data is already present in the csv file then it will overwrite the existing data with new one.
So instead of using
Export-Csv "\\termserv\d$\term\User\Reservations1.csv"
You cand use
Export-Csv "\\termserv\d$\term\User\Reservations1.csv" -Force -Append -NoTypeInformation
Here -Append will append the data in the csv file. Not overwrites.

Related

PowerShell - Add imported csv column into newly exported csv

I was hoping someone can help me out. I am trying to get the date a license was assigned to a user and export it to a new csv. The import csv contains the UserPrincipalName. I was able to narrow down to only show which license I want but having the UPN show next to the license/date would complete this script. Thanks in advance
$getusers = Import-csv -Path 'C:\test\userlist.csv'
foreach ($user in $getusers) {
(Get-AzureADUser -searchstring $User.UserPrincipalName).assignedplans | where {$_.Service -eq 'MicrosoftOffice'} | Select-Object Service,AssignedTimeStamp |
Export-CSV -Path "C:\test\userlist-export.csv" -notypeinformation
}
I would do it this way, first querying the user and storing it in a variable and then filter the AssignedPlans where Service = MicrosoftOffice. To construct the objects you can use [pscustomobject]. Worth noting, the call to Export-Csv should be the last statement in your pipeline (it shouldn't be inside the loop), otherwise you would be replacing the Csv with a new value on each loop iteration instead of appending data.
Import-Csv -Path 'C:\test\userlist.csv' | ForEach-Object {
$azUser = Get-AzureADUser -ObjectId $_.UserPrincipalName
foreach($plan in $azUser.AssignedPlans) {
if($plan.Service -eq 'MicrosoftOffice') {
[pscustomobject]#{
UserPrincipalName = $azUser.UserPrincipalName
Service = $plan.Service
AssignedTimeStamp = $plan.AssignedTimeStamp
}
}
}
} | Export-Csv "C:\test\userlist-export.csv" -NoTypeInformation

Passing PowerShell Output to CSV/Excel

I previously had asked a question regarding adding together files and folders with a common name and having them summed up with a total size (Sum of file folder size based on file/folder name). This was successfully answered with the PS script below:
$root = 'C:\DBFolder'
Get-ChildItem "$root\*.mdf" | Select-Object -Expand BaseName |
ForEach-Object {
New-Object -Type PSObject -Property #{
Database = $_
Size = (Get-ChildItem "$root\$_*\*" -Recurse |
Measure-Object Length -Sum |
Select-Object -Expand Sum ) / 1GB
}
}
This now leaves me with a list that is ordered by the 'Database' Property by default. I have attempted to use a Sort-Object suffix to use the 'Size' property with no joy. I have also attempted to use Export-Csv with confounding results.
Ideally, if I could pass the results of this script to Excel/CSV so I can rinse/repeat across multiple SQL Servers and collate the data and sort within Excel, I would be laughing all the way to the small dark corner of the office where I can sleep.
Just for clarity, the output is looking along the lines of this:
Database Size
-------- ----
DBName1 2.5876876
DBName2 4.7657657
DBName3 3.5676578
Ok, it was one pipe character that I had missed when using the Export-csv function. This resolved my problem.
$root = 'C:\DB\Databases'
Get-ChildItem "$root\*.mdf" | Select-Object -Expand BaseName |
ForEach-Object {
New-Object -Type PSObject -Property #{
Database = $_
Size = (Get-ChildItem "$root\$_*\*" -Recurse |
Measure-Object Length -Sum |
Select-Object -Expand Sum ) / 1GB
}
} | Export-Csv 'C:\Test\test.csv'

Export Powershell command to Excel

I have the following command
Get-WmiObject win32_OperatingSystem |%{"Total Physical Memory: {0}KB`nFree Physical Memory : {1}KB`nTotal Virtual Memory : {2}KB`nFree Virtual Memory : {3}KB" -f $_.totalvisiblememorysize, $_.freephysicalmemory, $_.totalvirtualmemorysize, $_.freevirtualmemory}
I want to export the above output to an excel file. I have:
Get-WmiObject win32_OperatingSystem |%{"Total Physical Memory: {0}KB`nFree Physical Memory : {1}KB`nTotal Virtual Memory : {2}KB`nFree Virtual Memory : {3}KB" -f $_.totalvisiblememorysize, $_.freephysicalmemory, $_.totalvirtualmemorysize, $_.freevirtualmemory} | Select-Object VisibleMem, FreeMem, VirtualMem,FreeVirtualMem | Export-Csv -Path "C:\Test.csv" -Encoding ascii -NoTypeInformation -UseCulture
This doesn't output anything besides titles of columns.I am looking for the output in each column. Any help?
You're throwing away the object with its properties when you create the the strings in your Foreach-Object loop so you don't have anything to export to csv anymore.
The property names in Select-Object doesn't exist. You can't make up column names (without using calculated properties/columns, see sample of this below).
Try this to output the data:
Get-WmiObject win32_OperatingSystem |
Select-Object TotalVisibleMemorySize, FreePhysicalMemory, TotalVirtualMemorySize, FreeVirtualMemory |
Export-Csv -Path "C:\Test.csv" -Encoding ascii -NoTypeInformation -UseCulture
If you need different column-names:
Get-WmiObject win32_OperatingSystem |
Select-Object #{n="VisibleMem";e={$_.TotalVisibleMemorySize}}, #{n="FreeMem";e={$_.FreePhysicalMemory}}, #{n="VirtualMem";e={$_.TotalVirtualMemorySize}}, #{n="FreeVirtualMem";e={$_.FreeVirtualMemory}} |
Export-Csv -Path "C:\Test.csv" -Encoding ascii -NoTypeInformation -UseCulture
If you need to write the text to the screen (for the user to see) while also saving them you would need to use Write-Host and remember to let the object passthrough to the next cmdlet in the pipeline:
Get-WmiObject win32_OperatingSystem |
ForEach-Object {
#Write to screen
Write-Host ("Total Physical Memory: {0}KB`nFree Physical Memory : {1}KB`nTotal Virtual Memory : {2}KB`nFree Virtual Memory : {3}KB" -f $_.totalvisiblememorysize, $_.freephysicalmemory, $_.totalvirtualmemorysize, $_.freevirtualmemory);
#Throw the original object to the next cmdlet in the pipeline
$_
} |
Select-Object TotalVisibleMemorySize, FreePhysicalMemory, TotalVirtualMemorySize, FreeVirtualMemory |
Export-Csv -Path "C:\Test.csv" -Encoding ascii -NoTypeInformation -UseCulture

Removing text in a string between two characters using Powershell

I have a powershell script that runs and collects information and puts it in a .csv file. A sample of the information looks like what is listed below, with each line starting with a unique server name followed by a random unique identifier in contained a pair of ( ).
"GDR01W01SQ004 (e785754f-eeb1)","1","4","63","NY-TER-PLN-P-5N"
"GDR01L02D001 (4b889a4d-d281)","4","12","129","CO-FDP-STE-NP-5N"
I have a second powershell script that runs and takes this .csv file and its information and formats it into a report with a header and proper spacing.
Can someone please assist me with removing the text in between the ( ) as well as the ( )?
I would like the entries for each line to look like the following:
"GDR01W01SQ004","1","4","63","NY-TER-PLN-P-5N"
Thank you very much in advance!
Here is the script I have been using.
####################PowerCLI Check####################
# Verify whether the PowerCLI module is loaded, if not load it.
if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin VMware.VimAutomation.Core -ErrorAction Stop
}
################### Run Time Section ####################
#This script should be run from a server that has DNS records for all entries in vcenters.txt
$file = get-Content c:\reports\vcenter\vcenters.txt
foreach ( $server in $file) {
Connect-VIserver -Server $server
Get-VM | select Name, NumCpu, MemoryGB, ProvisionedSpaceGB, Notes | Out-Null
}
# Command for Custom Annotations.
Get-VM | select Name, NumCpu, MemoryGB, ProvisionedSpaceGB, Notes -expandproperty customfields | Export-Csv -path “c:\reports\vcenter\vcenall.csv” -NoTypeInformation
# Takes vcenall.csv and sorts only the Name and Notes columns and selects all but the custom fields. Capacity Reporting script caprep.ps1 runs against this csv.
Import-csv c:\reports\vcenter\vcenall.csv | Sort-Object Notes, Name | Select-Object Name, NumCpu, MemoryGB, ProvisionedSpaceGB, Notes |Export-csv capacity.csv -NoTypeInformation
#Used to remove domain from server name
(Get-Content capacity.csv) | ForEach-Object { $_ -replace ".domain.local", "" } | Set-Content capacity.csv
# Takes vcenall.csv and sorts only the Notes column and selects only the Name and Notes columns. Nimsoft comparison script nimcomp.ps1 runs against this csv.
Import-csv c:\reports\vcenter\vcenall.csv | Sort-Object Notes | Select-Object Name, Notes | Export-csv nimsoft.csv -NoTypeInformation
# Takes vcenall.csv and sorts only the Name columns and exports all fields. Backup/Restore comparison script bure.ps1 runs against this csv.
Import-csv c:\reports\vcenter\vcenall.csv | Sort-Object Name | Export-csv bure.csv -NoTypeInformation
I think you need to add more information but just using what you have let try this one approach
Import-Csv C:\temp\test.csv -Header server,1,2,3,4 | ForEach-Object{
$_.server = (($_.server).split("(")[0]).Trim()
$_
}
We import the csv data and assign a header. If you already have one then this parameter can be omitted.
Then we examine each row of data as an object. Change the server data by splitting it up by its spaces. If this data is for server names then it is safe to assume that that everything before the first space is the server name. This approach is dependent on the space being there. We could also use the same logic with the ( but this would be easier if the space was a guarantee.
So we update the server and then send the data back down the pipe with $_.
Sample Output
server 1 2 3 4
------ - - - -
GDR01W01SQ004 1 4 63 NY-TER-PLN-P-5N
GDR01L02D001 4 12 129 CO-FDP-STE-NP-5N
Edit based on comments
Since it is a server display name I changed the logic to split based on the "(". Also using the Split() method instead of the -split operator.

Outputting PowerShell data to a string

This is really PowerShell 101, I realise, but I'm stuck.
I'm trying to iterate through a folder tree, getting each subfolder name and a count of files. No problems there.
The new requirement is to get the ACLs on each subfolder as well. All of this data needs to be output as a CSV file, with a line consisting of each folder name, the file count, and the ACLs in a single string in one field of the CSV (I was going to delimit them with semicolons).
I am open to exporting to XML if the data can be viewed in Excel.
The part where I'm stuck is getting the ACL information into a single string for the CSV.
Get-ACL on each directory shows the data as follows (I'm doing a Select to just get the IdentityReference and FileSystemRights, which is all we're interested in):
IdentityReference FileSystemRights
----------------- ----------------
BUILTIN\Users ReadAndExecute, Synchronize
BUILTIN\Users AppendData
BUILTIN\Users CreateFiles
I would like the output file formatted with one line per subdirectory, similar to
#filecount,folder,perms
51,C:\temp,BUILTIN\Users:ReadAndExecute,Synchronize;BUILTIN\Users:AppendData...
I however can't get any kind of join working to have it presented in this way. I don't care about what combination of delimiters are used (again, must be readable in Excel).
The script, such as it is, is as follows. The output file has its line of data appended with each directory it traverses. I'm sure this isn't very efficient, but I don't want the process consuming all the server memory either. The bits I can't figure out are prepended with ###.
(Get-ChildItem C:\temp -recurse | Where-Object {$_.PSIsContainer -eq $True}) | foreach {
$a = ($_.GetFiles().Count)
$f = $_.FullName
$p = (get-acl $_.FullName).Access | select-object identityreference,filesystemrights
### do something with $p?
Out-File -FilePath c:\outfile.csv -Append -InputObject $a`,$f`,###$p?
}
Since you want all ACEs of a folder mangled into a single line you need something like this:
Get-ChildItem 'C:\temp' -Recurse | ? { $_.PSIsContainer } | % {
# build a list of "trustee:permissions" pairs
$perms = (Get-Acl $_.FullName).Access | % {
"{0}:{1}" -f $_.IdentityReference, $_.FileSystemRights
}
New-Object -Type PSObject -Property #{
'Filecount' = $_.GetFiles().Count
'Folder' = $_.FullName
'Permissions' = $perms -join ';' # join the list to a single string
}
} | Export-Csv 'c:\outfile.csv' -NoType
Repeated appending inside a loop usually guarantees poor performance, so it should be avoided whenever possible. The outer loop creates a list of custom objects, which can then be exported via Export-Csv in a single go.

Resources