Output data with no column headings using PowerShell - powershell

I want to be able to output data from PowerShell without any column headings. I know I can hide the column heading using Format-Table -HideTableHeaders, but that leaves a blank line at the top.
Here is my example:
get-qadgroupmember 'Domain Admins' | Select Name | ft -hide | out-file Admins.txt
How do I eliminate the column heading and the blank line?
I could add another line and do this:
Get-Content Admins.txt | Where {$_ -ne ""} | out-file Admins1.txt
But can I do this on one line?

In your case, when you just select a single property, the easiest way is probably to bypass any formatting altogether:
get-qadgroupmember 'Domain Admins' | foreach { $_.Name }
This will get you a simple string[] without column headings or empty lines. The Format-* cmdlets are mainly for human consumption and thus their output is not designed to be easily machine-readable or -parseable.
For multiple properties I'd probably go with the -f format operator. Something along the lines of
alias | %{ "{0,-10}{1,-10}{2,-60}" -f $_.COmmandType,$_.Name,$_.Definition }
which isn't pretty but gives you easy and complete control over the output formatting. And no empty lines :-)

A better answer is to leave your script as it was. When doing the Select name, follow it by -ExpandProperty Name like so:
Get-ADGroupMember 'Domain Admins' | Select Name -ExpandProperty Name | out-file Admins.txt

If you use "format-table" you can use -hidetableheaders

add the parameter -expandproperty after the select-object, it will return only data without header.

The -expandproperty does not work with more than 1 object. You can use this one :
Select-Object Name | ForEach-Object {$_.Name}
If there is more than one value then :
Select-Object Name, Country | ForEach-Object {$_.Name + " " + $Country}

Joey mentioned that Format-* is for human consumption. If you're writing to a file for machine consumption, maybe you want to use Export-*? Some good ones are
Export-Csv - Comma separated value. Great for when you know what the columns are going to be
Export-Clixml - You can export whole objects and collections. This is great for serialization.
If you want to read back in, you can use Import-Csv and Import-Clixml. I find that I like this better than inventing my own data formats (also it's pretty easy to whip up an Import-Ini if that's your preference).

First we grab the command output, then wrap it and select one of its properties. There is only one and its "Name" which is what we want. So we select the groups property with ".name" then output it.
to text file
(Get-ADGroupMember 'Domain Admins' |Select name).name | out-file Admins1.txt
to csv
(Get-ADGroupMember 'Domain Admins' |Select name).name | export-csv -notypeinformation "Admins1.csv"

$server = ('*')+(Read-Host -prompt "What Server Context?")+'*'
$Report = (Get-adcomputer -SearchBase "OU=serverou,DC=domain,DC=com" -filter {name -like $server} -SearchScope Subtree|select Name |Sort -Unique Name)
$report.Name | Out-File .\output\out.txt -Encoding ascii -Force
$Report
start notepad .\output\out.txt
Put your server SearchBase in above.
If you are not sure what your server OU is try this function below...
#Function Get-OSCComputerOU($Computername)
{
$Filter = "(&(objectCategory=Computer)(Name=$ComputerName))"
$DirectorySearcher = New-Object System.DirectoryServices.DirectorySearcher
$DirectorySearcher.Filter = $Filter
$SearcherPath = $DirectorySearcher.FindOne()
$DistinguishedName = $SearcherPath.GetDirectoryEntry().DistinguishedName
$OUName = ($DistinguishedName.Split(","))[1]
$OUMainName = $OUName.SubString($OUName.IndexOf("=")+1)
# $Obj = New-Object -TypeName PSObject -Property #{"ComputerName" = $ComputerName
# "BelongsToOU" = $OUMainName
# "Full" = $DistinguishedName}
$Obj = New-Object -TypeName PSObject -Property #{"Full" = $DistinguishedName}
$Obj
}
Makes sure to run the Get-OSCComputerOU Servername with a select -expandproperty Full filter.
Then just plug in the response to the Searchbase...
All thanks to http://www.jaapbrasser.com

Related

Powershell AD: filter description -like $variable => contains $variable

My task include to filter all users names in group and subgroup in AD. Continue to filter the computers and show just those, which contains filtered names.The problem is, that description includes also other characters like space or "NEW".
My code:
foreach ($file in Get-ADGroupMember -Identity GroupName -Recursive) {Get-ADComputer -Filter 'Description -like $file.name' -Property Name,Description | Select -Property Name,Description}
It would be great to just add * or change -like to -include :D But...
My begginers question is: How to write the code to see all results, not just the ones which match exactly the $file.name?
Thank you for ur time!
Your initial problem was in the Filter you used. With the correct quoting and using the sub-expression operator $() that fixed it.
However, as promised in my comment, here's what I mean on how you can create a report of group members (both users, computers and if you like also subgroups).
Since all objects returned from the Get-ADGroupMember cmdlet have an .objectClass property, you can use that to determine what next Get-AD* cmdlet you can use.
Here, I'm capturing the collected objects output in the foreach() loop in a variable that you can show on screen, or save as Csv file you can open in Excel for instance.
$groupName = 'GroupName'
$result = foreach($adObject in (Get-ADGroupMember -Identity $groupName -Recursive)) {
# use the proper Get-AD* cmdlet depending on the type of object you have
switch ($adObject.objectClass) {
'user' {
$adObject | Get-ADUser -Properties Description | Select-Object Name, Description, #{Name = 'Type'; Expression = {'User'}}
}
'computer' {
$computer = $adObject | Get-ADComputer -Properties Description
# you want to output only the computers where the Description property holds the computer name
if ($computer.Description -like '*$($computer.Name)*') {
$computer | Select-Object Name, Description, #{Name = 'Type'; Expression = {'Computer'}}
}
}
# perhaps you don't want subgroups in your report, in that case just remove or comment out the next part
'group' {
$adObject | Get-ADGroup -Properties Description | Select-Object Name, Description, #{Name = 'Type'; Expression = {'Group'}}
}
}
}
# show the result on screen
$result | Format-Table -AutoSize
# save the result as Csv file
$outFile = Join-Path -Path 'X:\Somewhere' -ChildPath ('{0}_members.csv' -f $groupName)
$result | Export-Csv -Path $outFile -NoTypeInformation -UseCulture
The -UseCulture switch makes sure the Csv file uses the delimiter character your local Excel expects. Without that, a comma is used
Interesting reads:
about_Operators
Adam the Automator
Learn Powershell | Achieve More
and of course StackOverflow

Filter enabled AD users from CSV file

I have a script to import a list of users and want to check if any of these users are disabled. I did try to run the script below but it doesn't filter the users in the CSV file it filters everyone in the entire organization. any suggestions would be appreciated. displayname and SIP address in one of the headers in the CSV file if needed to use the header.
Import-CSV -Path .\Piscataway-+1732.csv | ForEach-Object {
Get-ADUser -Filter "Enabled -eq '$true'" | select Enabled,EmailAddress,SamAccountName
} | Export-CSV .\results77.csv -NoTypeInformation
You have several issues:
You are piping From Import-Csv to ForEach-Object. So Get-ADUser doesn't really know you are piping it input objects.
Get-ADUser's -Identity parameter is by value, not by property name. so you need to echo the appropriate column to send it down the pipe.
If you pipe and use the -Filter parameter the filter is going to apply to the whole domain. It's not going to limit the filter to what you piped in.
If you want the email address to be output you have to tell Get-ADUser to retrieve it.
Try something like this:
Import-CSV -Path .\Piscataway-+1732.csv |
ForEach-Object{ $_.samAccountName }
Get-ADUser -Properties mail |
Where-Object{ $_.Enabled }
Select-Object Enabled,mail,SamAccountName |
Export-CSV .\results77.csv -NoTypeInformation
Note: The Property for the email address is "mail".
Note: Since we don't have a sample of the CSV file the above example
assumes there's a column names samAccountName.
Now, if you want the output to come from the CSV file but validate it according to the user's status in AD we have to change the approach. As always there are several ways to do this.
Example 1:
Import-CSV -Path "c:\temp\test.csv" |
Select-Object #{Label = 'Enabled'; Expression = { ( Get-ADUser $_.samAccountName ).Enabled } },EmailAddress,samAccountName |
Export-CSV -Path "c:\temp\Output.csv" -NoTypeInformation
This again assumes the column name (samAccountName). It also assumes there is not already an "enabled" column. So we are adding a property called enabled that we're getting via Get-ADUser. Then finally re-exporting to Csv.
Example 2:
$CsvData = Import-CSV -Path "c:\temp\test.csv"
$EnabledUsers =
(
$CsvData |
ForEach-Object{ $_.samAccountName } |
Get-ADUser |
Where-Object{ $_.Enabled }
).samAccountName
$CsvData |
Where-Object{ $EnabledUsers -contains $_.samAccountName } |
Select-Object #{Label = 'Enabled'; Expression = { $true } },EmailAddress,samAccountName |
Export-Csv -Path "c:\temp\Output.csv" -NoTypeInformation
Example 1 is great for small jobs but too many individual calls to Get-ADUser might be slow for larger runs. In this example Import the CSV data once. Then use it to get a flat list of those entries that are enabled in AD. Once you have that you can use the -contains operator to check if the account is enabled. Once again there's a little extra work to add the "Enabled" property.
This should give you a general idea. There are probably a dozen more ways to do this, but hopefully this give you a good idea of what has to happen. Let me know if this helps.

Allocating values to specific csv columns in Powershell

I'd like to ask if anybody can please advise a way how to allocate a value in variable to a column in csv.
For example:
TriggeredBy | TriggeredTime | Firstname | Lastname | Username | ....
Throughout my script I'm modifying input data and on the go I'd like it to fill in the row to the relevant column.
Then another script from a different server has to take over, read the calculated values and add its calculated results into its dedicated columns.
The output would be a row where I can see that all the results.
In the end it's supposed to serve as a sort of database.
Sample of script here would be:
$aduser = Get-ADUser -Filter {sAMAccountName -like $username} -Properties *
$Firstname = $aduser.GivenName
$Firstname | Export-CSV -Path $filepath | Select-Object "First Name"
$Lastname = $aduser.Surname
$Lastname | Export-CSV -Path $filepath | Select-Object "Last Name"
$TriggeredBy = $env:UserName
$TriggeredBy | Export-CSV - Path $filepath | Select-Object "TriggeredBy"
...
Throughout the process all saved in one relevant row. Next process does the same for the following row etc...
The "Export-CSV ...." part is obviously wrong, I would need some alternative
Many thanks!
Use Select-Object with calculated properties:
Get-ADUser -Properties * -Filter "sAMAccountName -eq `"$username`"" | #`
Select-Object #{ n='FirstName'; e='GivenName' },
#{ n='Last Name'; e='Surname' },
#{ n='TriggeredBy'; e={ $env:UserName } } |
Export-Csv -NoTypeInformation -Literalpath $filePath
Note that I've used a string as the -Filter argument, because that's what it ultimately becomes anyway. Using script-block literal syntax { ... } is tempting, but ultimately causes more problems than it solves - see this answer.
Note that in Windows PowerShell Export-Csv creates ASCII(!)-encoded files by default, which can result in loss of information; use the -Encoding parameter to change that.
PowerShell [Core] v6+, by contrast, commendably defaults to (BOM-less) UTF-8; also, the
-NoTypeInformation switch is no longer necessary there.
If you want to append to an existing CSV file (which needs to have the same column structure), use the -Append switch.

Create Shortcut based on an AD HomeDirectory

I'm Trying to create a script to create shortcuts for students based on their AD HomeDirectory and naming the Link as there AD display name. Homedirectory is a UNC path.
However when i get to the $shortcut.targetpath area it complains about invalid parameter. I think it's not liking the data in the $homedir variable. My code is noobish. But i'm still learning. Any help would be great.
###Read a Sisweb Extract
$data=Get-Content C:\studentfile.txt
###For each row in the file execute all of this
foreach ($line in $data)
{
###Parse the row and retrieve SSID
$columns = $line -split '\t'
$studentid = $columns[3]
###If a SSID is found execute the following code.
if($studentid -match "[0-9]")
{
###Retrieve DisplayName of the SSID.
$displayname=Get-aduser $studentid -property displayname |ft displayname -hidetableheaders |out-string
###Retrieve Home Directory of the SSID
$homedir=Get-aduser $studentid -property homedirectory |ft homedirectory -hidetableheaders |out-string
###Parse the homedirectory data and retrieve the servername.
$pathdata="$homedir" -split '\\'
$server=$pathdata[2]
###Create Shortcut
$WshShell=New-Object -comObject WScript.Shell
$Shortcut=$WshShell.CreateShortcut("C:\temp\$displayname.lnk")
$Shortcut.TargetPath="$homedir"
$Shortcut.Save()
}
}
I am going to build an answer since i see a couple of things that should be addressed. Ultimately I think your issue lies with your assignment of $homedir.
if($studentid -match "[0-9]") This code will check to see if $studentid contains a single numerical digit. Was this on purpose? Currently you would get a hit if an ID was sdfhgkjhg3kjg since that contains one digit. A simple addition would be to change it to if($studentid -match "^[0-9]{6}$") for example. Means that it will match a single line that contained exactly 6 digits.
$displayname=Get-aduser $studentid -property displayname |ft displayname -hidetableheaders |out-string I see this twice. I would update this since the Format-Table doesnt really serve a purpose and you can use Select-Object to accomplish your goal.
Get-aduser $studentid -property displayname | select -first 1 -ExpandProperty displayname
Get-aduser $studentid -property homedirectory | select -first 1 -ExpandProperty homedirectory
OR
Instead of call get-aduser twice you could combine both your variable assignments.
$singleStudent = Get-aduser $studentid -property homedirectory,displayname
$displayname = $singleStudent.DisplayName
$homedir = $singleStudent.HomeDirectory

PowerShell: How can I list the index of an item using format-table?

I wish to list the index of an item in a result table.
In this case I am using get-aduser with the filter option.
I am then using format-table with -Property to display only the properties I want.
I previously used a loop to display the items along with a counter to emulate the index but this was messy and I wanted it in a table.
Code:
$search_param = read-host "Enter search string: "
$search_param = "*" + $search_param + "*" # Construct search param.
$search_result = Get-ADUser -Filter {Surname -like $search_param -or GivenName -like $search_param -or SamAccountName -like $search_param}
$search_result | format-table -Property GivenName,Surname,SamAccountName
How can I get format-table to display the item index/position without using some kind of loop? ie, is there some kind of 'hidden' index property that I can simply provide to format-table?
The format-table CmdLet -Property param can be a new calculated property see Format-table help.
Here is an example with a computed index on Get-Process objects.
$index=0
Get-Process | Format-Table -Property #{name="index";expression={$global:index;$global:index+=1}},name,handles
The ForEach-Object cmdlet can be used to create a calculated "index" property for the Format-Table cmdlet
For Example:
$search_result | ForEach-Object {$index=0} {$_; $index++} | Format-Table -Property #{ Label="index";Expression={$index}; Width=5 },GivenName,Surname,SamAccountName
Additional References:
Adding Array Index Numbers to PowerShell Custom Objects
ForEach-Object
Format-Table
In my opinion you can't, you need to extend the objects with an Index property and include it in your Format-Table command.
$procs = Get-Process
#option 1
$procs | Select #{N='Index'; E={$procs.IndexOf($_)}}, name, handles
#option 2
$procs | Format-Table -Property #{name="index";expression={$procs.IndexOf($_)}},name,handles