Exporting array results to csv using powershell - powershell

I'm working on a powershell script utilizing the Citrix XenApp sdk. What I am trying to do is get the following values using one of the citrix cmdlets; Load, User count, and Server count (which uses another cmdlet) and export to csv.
I created a csv file that contains the name of the delivery groups I want to query, so I import that csv and start my array by calling a couple of the citrix cmdlets:
# Add Citrix XenApp sdk
Add-PSSnapin Citrix.*.Admin.V*
# Define Dashboard Server Name as well as import the Delivery Group csv file.
$DashboardServer = "server.name"
$delivery_group_csv = Import-Csv \\$DashboardServer\path_to_file\file.csv -Delimiter ","
# extract citrix loads per delivery group as well as Session counts for each delivery group
foreach($silo in $delivery_group_csv) {
$DeliveryGroupName = $silo.DeliveryGroupName
$LoadIndex = Get-BrokerMachine -DesktopGroupName $DeliveryGroupName
$SiloLoad = ($LoadIndex | Measure-Object 'LoadIndex' -Sum).Sum/1000
$UserCount = ($LoadIndex | Measure-Object 'SessionCount' -Sum).Sum
$ServerCount = Get-BrokerDesktopGroup -Name $DeliveryGroupName
$DG_servercount = ($ServerCount).TotalDesktops
Write-Host $DeliveryGroupName "- Load" $SiloLoad"%" " - Servercount" $DG_servercount "- " Total Users" - " $UserCount | Export-Csv -Path \\$DashboardServer\path_to_save\new_file.csv -Append -Encoding UTF8 -NoTypeInformation
The problem is when it gets exported to csv I only get a blank csv file. I am fairly new to powershell and have tried a variety of things, but completely at a loss to get this to work. Any help would be greatly appreciated.

Related

Export installed software to csv from multiple remote systems

My script does (somewhat) what it's supposed to do if I need the information from the local PC. I have it reaching to a txt file for a list of computers. The script will read the list and show "Processing:..." for the list of computers but the export only shows the local system. Even if I remove my local PC from the txt file, the export to csv still only shows the local system. It does create the correct columns and populates accordingly. I just need it to pull the data from remote systems as well. Since the script will be used by multiple people, the variables allow the txt file and output file to be on their systems.
Function Export-InstalledSoftware {
Process {
if (Test-Connection -ComputerName $_ -count 1 -quiet)
{
echo "Processing: $env:COMPUTERNAME"
Get-ItemProperty -path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*,HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* `
| Select-object #{n='ComputerName';e={$env:COMPUTERNAME}},#{n='DisplayName';e={$_.displayName}},#{n='Publisher';e={$_.Publisher}},#{n='DisplayVersion';e={$_.DisplayVersion}} `
| Sort displayName `
| Export-CSV C:\Users\$(get-content env:username)\Desktop\"SoftwareQuery_"$(get-date -f yyyy-MM-dd)".csv" -NoTypeInformation -Encoding ASCII
}
}
}
Get-Content "C:\Users\$(get-content env:username)\Desktop\systems.txt" -readcount 1 | Export-InstalledSoftware

Printer Migration - Powershell script

I have found some great examples on foreach loops in Powershell here but I just can't wrap my head around foreach loops for what I am doing.
I found great scripts that deal with migrating printer when migrating from one Windows print server to another however my challenge is that I am migrating from an Novell iPrint server to a Windows server.
The struggle is that the printer name or share name (or any printer property) for iPrint printer is not the hostname so I have to come up with some translation table with iPrint name and Printer hostname.
Initially, I wanted to just have column 2 of my translation table have it execute my powershell command to install a network printer which would make things easier.
I am in the process of trying to create a logon script to query printers that are installed on computer and have it do a 'foreach' loop against a CSV with iPrint names and hostnames.
csv 1
installediprintprintername1
installediprintprintername2
installediprintprintername3
printtranslationtable.csv
column 1 column 2
iprintprintername1 hostnameprinter1
iprintprintername2 hostnameprinter2
iprintprintername3 hostnameprinter3
iprintprintername4 hostnameprinter4
This is what I got so far but not able to get it to work. Any help would be appreciated!
$printers = #(Get-wmiobject win32_printer)
$path = "\\networkdrive\printtranslationtable.csv"
$printertranslation = Import-Csv -path $path
foreach ($iprintprinter in $printtranslationtable) {
foreach ($name in $csv1) {
if ($name -eq $printtranslationtable.column1) {
Write-Host $newPrinter = $printtranslationtable.column2
}
}
}
Update
So I was able to tweak the script #TheMadTechnician suggested and able to get this PS script to work in my environment. What I am trying to do is to check if new printers are installed and if they are then just exit script. This is what I have but can't get it to exit or break. I was also trying to write the new printers into text file but not necessary, I would like for it to stop executing script.
if (($printers.name -like "\winprint*") -eq $true) {
$printers.name -like "\winprint\" | out-file -FilePath "C:\windowsprinters.txt" -Append
{break} {exit}
}
When you read the file with Import-Csv, PowerShell creates an array of custom objects with property names from the header line. On the other hand Get-Content produces simple array of string values. I came up with this one liner, which goes thru the translation table and checks if the printer list contains one. This is not optimal if you have billions of printers, but keeps things clear:
printers.txt:
iprinter2
iprinter3
printertable.csv:
"Column1";"Column2"
"iprinter1";"hostname1"
"iprinter2";"hostname2"
"iprinter3";"hostname3"
"iprinter4";"hostname4"
PowerShell:
$printers = Get-Content .\printers.txt
$prtable = Import-Csv -Delimiter ";" .\printertable.csv
$prtable | ?{ $printers -contains $_.Column1 } | %{Write-Host "Install $($_.Column2)"}
Ok, so you query what printers are installed, and you have a translation table loaded from a CSV, now you just need to look at that translation table and cross reference which entries have a listing in the local computer's printer listings.
$printers = #(Get-wmiobject win32_printer)
$path = "\\networkdrive\printtranslationtable.csv"
$printertranslation = Import-Csv -path $path
$printertranslation | Where{$_.Column1 -in $printers.ShareName} | ForEach{ Add-Printer $_.Column2 }
I don't know what property of the win32_printer object aligns best for you, but I would suggest ShareName or DeviceId. Those should be something like:
ShareName: XeroxColor02
DeviceId: \\printserver\XeroxColor02

Extract data from unstructured text file to CSV using PowerShell

I am trying to export domain time II windows slave PTP logs to Splunk. The log file is unstructured. I tried using regex extractor of splunk to extract the field but it will be an unreliable solution.
Is there a way to extract the required data in CSV format using PowerShell?
If you can write the RegEx that extracts the required data into one or more 'capturing groups', then the results can be exported to CSV quite easily. Something along the lines of:
$RegEx = "your regex here"
$FilePath = "path to file"
$PropertySelectors = #(
${n="Field_1";e={$_.Groups[1].Value}},
${n="Field_2";e={$_.Groups[2].Value}},
${n="Field_3";e={$_.Groups[3].Value}}
# etc.
)
select-string -path $filePath -pattern $RegEx -allmatches |
select-object -ExpandProperty Matches |
select-object $PropertySelectors |
convertto-csv

exporting Powershell Script to CSV

We are getting ready to merge our AD with another. We have about 300 computers that I'm trying to match up with who uses them so the accounts and home folders migrate correctly, and I'm trying to think of the most efficient way to get this information.
We have everyone in an inventory system (Filemaker) (and will be implementing SCCM once we migrate (thank god) ) but we had a few errors when we did our first test batch. Im looking for something I can push out through group policy (possibly?) that will give me the computer name, logged in account, and them email it to me.
So far this is what I have.
[System.Environment]::UserName
[System.Environment]::UserDomainName
[System.Environment]::MachineName
Out-File T:\TEST.txt
But the output is blank. Any idea what I'm doing wrong here? Also is there a way to have this run on multiple computers but write to the same file?
"$env:USERNAME,$env:USERDOMAIN,$env:COMPUTERNAME" | Out-File 'T:\test.txt'
will write the name and domain of the currently logged-in user as well as the hostname of the local computer to the file T:\test.txt.
Using a single file may cause conflicts due to concurrent write attempts, though. It's better to use one file per computer, like this:
"$env:USERDOMAIN\$env:USERNAME" | Out-File "T:\$env:COMPUTERNAME.txt"
Run it as a logon script (or from a logon script), e.g. like this:
powershell -ExecutionPolicy Bypass -File "\\%USERDNSDOMAIN\netlogon\your.ps1"
Get-ADComputer -Filter * -Property * | Select-Object Name | Out-File C:\outdir\machinelist.txt -NoTypeInformation -Encoding UTF8
will get you all machine names, unless you have them already. Either way, use your list of machines in
$MachineList = Get-Content -Path c:\outdir\machinelist.txt;
foreach ($Machine in $MachineList){
($Machine + ": " + #(Get-WmiObject -ComputerName $Machine -Namespace root\cimv2 -Class Win32_ComputerSystem)[0].UserName) | Out-File "C:\outdir\result.txt" -Append
}
If you change the destination directory to somewhere that all computers have access to, it can run on multiple computers. It won't email it to you but you can just grab it.
You'll need to pipe those properties into the file like..
[System.Environment]::UserName, [System.Environment]::UserDomainName, [System.Environment]::MachineName | Out-File T:\Test.txt

Get virtual SCSI hardware on servers using Powershell

I'm trying to use Powershell to get SCSI hardware from several virtual servers and get the operating system of each specific server. I've managed to get the specific SCSI hardware that I want to find with my code, however I'm unable to figure out how to properly get the operating system of each of the servers. Also, I'm trying to send all the data that I find into a csv log file, however I'm unsure of how you can make a powershell script create multiple columns.
Here is my code (almost works but something's wrong):
$log = "C:\Users\me\Documents\Scripts\ScsiLog.csv"
Get-VM | Foreach-Object {
$vm = $_
Get-ScsiController -VM $vm | Where-Object { $_.Type -eq "VirtualBusLogic" } | Foreach-Object {
get-VMGuest -VM $vm } | Foreach-Object{
Write-output $vm.Guest.VmName >> $log
}
}
I don't receive any errors when I run this code however whenever I run it I'm only getting the name of the servers and not the OS. Also I'm not sure what I need to do to make the OS appear in a different column from the name of the server in the csv log that I'm creating.
What do I need to change in my code to get the OS version of each virtual machine and output it in a different column in my csv log file?
get-vmguest returns a VMGuest object. Documented here: http://www.vmware.com/support/developer/PowerCLI/PowerCLI51/html/VMGuest.html. The documentation is sparse, but I would guess the OSFullName field would give you the OS version. So you could change the write-output line to
add-content $log "$($vm.guest.vmname) , $($vmguest.guest.OSFullName)"
and you'd be on the right track. The comma in the output is what makes the output "comma separated values". A CSV file can optionally have a header. (See Import-CSV / Export-CSV help for details). So you might want to add the following as the second line of your script:
add-content $log "VM Name, OS Name" # add CSV header line