Issue creating an array of objects from a csv file - arrays

I'm fairly new with Powershell, so this is likely a rookie mistake, but I am trying to take a CSV document containing only user display names, query AD for the required information, and populate that information into object properties using a hash table.
Here is what i have right now
$Path = "C:\Scripts\Generate-CSRSpreadsheets\Roster-Jpay.csv"
$Table = Import-csv -Path $Path -Header EmployeeDisplayName
$Array = #()
$ADUser = Get-ADUser -Properties DisplayName,Manager -Filter {DisplayName -eq $_.EmployeeDisplayname}
ForEach($User in $Table){
$Object = New-Object PSObject -Property #{
DisplayName = $ADUser.DisplayName
GivenName = $ADUser.GivenName
Surname = $ADUser.Surname
Email = $ADUser.Mail
}
$Array += $Object
}
This seems to me like it should work fine, but when I check my output it looks something like this:
Example Output Image
Let's say in this example I have 9 total users, but it's only outputting the information from the last user in the csv. I've been pouring over this code, but I can't see what's wrong with it. Any help would be appreciated.
Thank you

You need to move your Get-ADUser inside the loop:
$Path = "C:\Scripts\Generate-CSRSpreadsheets\Roster-Jpay.csv"
$Table = Import-csv -Path $Path -Header EmployeeDisplayName
$Array = #()
ForEach($User in $Table){
$ADUser = Get-ADUser -Filter "DisplayName -eq '$($User.EmployeeDisplayName)'" -Properties DisplayName,Manager
$Object = New-Object PSObject -Property #{
DisplayName = $ADUser.DisplayName
GivenName = $ADUser.GivenName
Surname = $ADUser.Surname
Email = $ADUser.Mail
}
$Array += $Object
}

Related

Object of arrays in powershell not showing anything in CSV

I have an object which contains multiple arrays of strings. Nothing I do can display these in a decent format in Powershell. I have looked everywhere on this site and many others and been unable to find an answer. Is this something that should be done with Python or a separate programming language? It appears powershell doesn't want users to export arrays to CSV. Anyways let me know if you all have a fix for this.
Import-Module VMware.VimAutomation.Core
Connect-VIServer -Server vcenter-appliance.swacu.net -Force $prodservers = get-vm | select Name Connect-VIServer -Server drvcenter-appliance.swacu.net -Force $replicaserversfull = get-vm | select Name
$notinprod = Foreach($replica in $replicaservers){
$shortname = $replica.name.trim('_replica')
$shortnametwo = if($shortname -like "*_TTN"){$shortname.trim('_TTN')}
$shortnames = New-Object -TypeName PSObject -Property #{
ShortName = $replica.name.trim('_replica')
}
if($prodservers.name -contains $shortname){
}
elseif($prodservers.name -contains $shortnametwo) {
}
else{
New-Object -TypeName PSObject -Property #{
SystemName = $replica.name
} | Select SystemName
} }
$NotInReplica = Foreach($prodserver in $prodservers){
$half = $replicaservers.name.trim('_replica')
$correct = if($half -like "*_TTN"){$half.trim('_TTN')}
if($half -contains $prodserver.name){
}
elseif($correct -contains $prodserver.name) {
}
else{
New-Object -TypeName PSObject -Property #{
SystemName = $prodserver.name
} | Select SystemName
}
}
Write-host $half $whole = New-Object -TypeName PSObject -Property #{
Replica = $replicaservers.name | out-string
Prod = $prodservers.name | out-string
NotInProd = $notinprod.SystemName | out-string
NotInReplication = $NotInReplica.SystemName | out-string
}
$whole | Select-Object prod, replica, NotInReplication, notinprod | Out-file -Path '.\Results\Noprod.csv'
This would be a fine output. Or having them each in their own column.
It appears powershell doesn't want users to export arrays to CSV.
Unless you use Export-CSV instead of Out-File.

What is the best format to export bigger output?

I have a big file server, with a big files and folder tree and I need export the NTFS permissions. I used a following script:
$FolderPath = Get-ChildItem -Path C:\FS -Filter * -Recurse -Force
ForEach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
ForEach ($Access in $Acl.Access) {
$Properties = [ordered]#{'Folder Name'=$Folder.FullName;'Group/User'=$Access.IdentityReference;'Permissions'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
New-Object -TypeName PSObject -Property $Properties
}
}
What kind of format recommend me to get out the result from the script, I think CSV is a very good format, but I don´t know if is the correct file format.
You can write to CSV format and it will be easier to process them later in excel or another place.
$FolderPath = Get-ChildItem -Path C:\FS -Filter * -Recurse -Force
$collection = #() #Define collection
ForEach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
ForEach ($Access in $Acl.Access) {
$Properties = [ordered]#{'Folder Name'=$Folder.FullName;'Group/User'=$Access.IdentityReference;'Permissions'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
$collection += New-Object -TypeName PSObject -Property $Properties
}
}
$collection | Export-Csv -LiteralPath C:\ACLInformation.csv -NoTypeInformation -Encoding UTF8

Powershell Array to csv

I'm pretty new to powershell and I cant figure out how to get my array into a csv file, where each string goes onto a new row. Below is some example code.
$ServerList = "E:\Coding Projects\Powershell\ServerNameList.txt"
$ServerNames = Get-content $ServerList
write-host $ServerNames
$OutputPath = "E:\Coding Projects\Powershell\Output.csv"
$Names = #()
$Outcome = #()
foreach ($Server in $ServerNames){
$Names += $Server
if ($Server -match "Joe"){
$Outcome += "pass"
}else{
$Outcome += "Fail"
}
}
$Names
$Outcome
$csv = New-object psobject -property #{
'User' = $Names -join ','
'Groups' = $Outcome -join ','
}
write-host $csv
$csv | Select-Object -property User, Groups | Export-csv -path $OutputPath -NoTypeInformation
When I check the csv file, all of the outputs appear on one row instead of iterating down the rowin its specific column.
Any help would be very useful and appreciated
Right now you're creating 2 separate arrays of string values - instead, you'll want to create a single array of objects with two properties:
$ServerList = "E:\Coding Projects\Powershell\ServerNameList.txt"
$ServerNames = Get-content $ServerList
write-host $ServerNames
$OutputPath = "E:\Coding Projects\Powershell\Output.csv"
$serversWithOutcome = #()
foreach ($Server in $ServerNames){
$serversWithOutcome += [pscustomobject]#{
User = $Server
Groups = $Server -match "Joe"
}
}
$serversWithOutcome | Export-csv -path $OutputPath -NoTypeInformation

Powershell-Azure WebApp IpRestrictions - WebApps Array

I have been struggling to come up with a working solution for days on this
What am I trying to achieve?
Foreach ($item in $webApps){
$WebAppConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/config -ResourceName $item -ResourceGroupName $resourceGroup -ApiVersion $APIVersion)
}
The issue is that "-resourceName" will not accept objects, but rather only a string
I am looking for a way to take the output of the following command, convert it to a string, so that it can satisfy –ResourceName, and loop through each item in the string
$webApps = (Get-AzureRmResourceGroup -Name $resourceGroup | Get-AzureRmWebApp).name
This returns a nice list of Azure WebApps that exist in a specified ResourceGroup, however they are in object form, which –ResourceName will not take
I have tried several ways to convert the output of $webApps to a string, add a comma to the end, then do a –split ',' but nothing seems to work for properly, where –ResourceName will accept it
Method 1:
[string]$webAppsArrays =#()
Foreach ($webApp in $webApps){
$webAp+',' -split ','
}
Method 2:
$
webApps | ForEach-Object {
$webApp = $_ + ","
Write-Host $webApp
}
Method 3:
$csvPath2 = 'C:\Users\Giann\Documents\_Git Repositorys\QueriedAppList2.csv'
$webApps = (Get-AzureRmResourceGroup -Name $resourceGroup | Get-AzureRmWebApp).name | out-file -FilePath $csvPath1 -Append
$csvFile2 = import-csv -Path $csvPath1 -Header Name
This ouputs a list in a CSV, however these are still objects, so I cannot pass each item into –ResourceName
I am going in circles trying to make the below a repeatable, looping script
The desired end result would be to use the below script, with an array of webApps, being queried from the provided resource group variable:
Any help would be greatly appreciated for how to use this script, but pull a dynamic list of WebApps from a specified Resource Group, keeping in mind the -ResourceName "String" restrictions in the $WebAppConfig variable
Here is the original script to create IP Restrictions for 1 Web App and 1 Resource Group, using properties from a CSV file:
#Create a Function to create IP Restrictions for 1 Web App and 1 Resource Group, using properties from the CSV file:
#Variables
$WebApp = ""
$resourceGroup =""
$subscription_Id = ''
#Login to Azure
Remove-AzureRmAccount -ErrorAction SilentlyContinue | Out-Null
Login-AzureRmAccount -EnvironmentName AzureUSGovernment -Subscription $subscription_Id
Function CreateIpRestriction {
Param (
[string] $name,
[string] $ipAddress,
[string] $subnetMask,
[string] $action,
[string] $priority
)
$APIVersion = ((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web).ResourceTypes | Where-Object ResourceTypeName -eq sites).ApiVersions[0]
$WebAppConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/config -ResourceName $WebApp -ResourceGroupName $ResourceGroup -ApiVersion $APIVersion)
$ipRestriction = $WebAppConfig.Properties.ipSecurityRestrictions
$ipRestriction.name = $name
$ipRestriction.ipAddress = $ipAddress
$ipRestriction.subnetMask = $subnetMask
$ipRestriction.action = $action
$ipRestriction.priority = $priority
return $ipRestriction
}
#Set csv file path:
$csvPath5 = 'C:\Users\Giann\Documents\_Git Repositorys\ipRestrictions5.csv'
#import CSV Contents
$ipRestrictionArray = Import-Csv -Path $csvPath5
$ipRestrictions = #()
foreach($item in $ipRestrictionArray){
Write-Host "Adding ipRestriction properties for" $item.name
$newIpRestriction = CreateIpRestriction -name $item.name -ipAddress $item.ipAddress -subnetMask $item.subnetMask -action $item.action -priority $item.priority
$ipRestrictions += $newIpRestriction
}
#Set the new ipRestriction on the WebApp
Set-AzureRmResource -ResourceGroupName $resourceGroup -ResourceType Microsoft.Web/sites/config -ResourceName $WebApp/web -ApiVersion $APIVersion -PropertyObject $ipRestrictions
As continuation on the comments, I really need multiline, so here as an answer.
Note that I cannot test this myself
This page here shows that the Set-AzureRmResource -Properties parameter should be of type PSObject.
(instead of -Properties you may also use the alias -PropertyObject)
In your code, I don't think the function CreateIpRestriction returns a PSObject but tries to do too much.
Anyway, try like this:
Function CreateIpRestriction {
Param (
[string] $name,
[string] $ipAddress,
[string] $subnetMask,
[string] $action,
[string] $priority
)
# There are many ways to create a PSObject (or PSCustomObject if you like).
# Have a look at https://social.technet.microsoft.com/wiki/contents/articles/7804.powershell-creating-custom-objects.aspx for instance.
return New-Object -TypeName PSObject -Property #{
name = $name
ipAddress = $ipAddress
subnetMask = $subnetMask
action = $action
priority = $priority
}
}
#Set csv file path:
$csvPath5 = 'C:\Users\Giann\Documents\_Git Repositorys\ipRestrictions5.csv'
#import CSV Contents
$ipRestrictionArray = Import-Csv -Path $csvPath5
# create an new array of IP restrictions (PSObjects)
$newIpRestrictions = #()
foreach($item in $ipRestrictionArray){
Write-Host "Adding ipRestriction properties for" $item.name
$newIpRestrictions += (CreateIpRestriction -name $item.name -ipAddress $item.ipAddress -subnetMask $item.subnetMask -action $item.action -priority $item.priority )
}
# here we set the restrictions we collected in $newIpRestrictions in the $WebAppConfig.Properties.ipSecurityRestrictions array
$APIVersion = ((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web).ResourceTypes | Where-Object ResourceTypeName -eq sites).ApiVersions[0]
$WebAppConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/config -ResourceName $WebApp -ResourceGroupName $ResourceGroup -ApiVersion $APIVersion)
$WebAppConfig.Properties.ipSecurityRestrictions = $newIpRestrictions
$WebAppConfig | Set-AzureRmResource -ApiVersion $APIVersion -Force | Out-Null
The code above will replace the ipSecurityRestrictions by a new set. You may want to consider first getting them and adding to the already existing list.
I found examples for Getting, Adding and Removing ipSecurityRestrictions here, but I can imagine there are more examples to be found.
Hope that helps.

Powershell read filenames under folder and read each file content to create menu items

I've a folder called c:\mycommands
files under this folder are multiple files like:
command1.txt
command2.txt
command3.txt
each file has one line only, like this:
in file command1.txt:
echo "this is command1"
in file command2.txt"
echo "this is command2"
and so on
I want to read the filename and it's content into an array/variable pair in order to build a dynamic menu.
so theoretically, all I would need to do in the future is to, drop a file into the folder and program will include it as menu option dynamically. (or remove the file to have it not show up in menu option.
What's the best way to approach this? maybe a do while loop with get-content into an array? Any input would be greatly appreciated. I'm really trying limit or avoid menu maintenance but would rather have the menu bre created dynamically
Here are three variations on the same basic idea, depending on what kind of output you need.
# Storing output in a hash table (key/value pairs)
$resultHash = #{}
Get-ChildItem -Path C:\mycommands -File |
ForEach-Object {$resultHash.Add($_.Name, (Get-Content -Path $_.FullName))}
# Storing output in an array of psobjects
$resultArray = #()
Get-ChildItem -Path C:\mycommands -File |
ForEach-Object {
$resultArray += (New-Object -TypeName psobject -Property #{"NameOfFile"=$_.Name; "CommandText"=(Get-Content -Path $_.FullName);})
}
# Outputting psobjects to the pipeline
Get-ChildItem -Path C:\mycommands -File |
ForEach-Object {
New-Object -TypeName psobject -Property #{"NameOfFile"=$_.Name; "CommandText"=(Get-Content -Path $_.FullName);}
}
# Making a nice menu out of the hash table version
$promptTitle = "My menu"
$promptMessage = "Choose from the options below"
$promptOptions = #()
foreach ($key in $resultHash.Keys)
{
$promptOptions += New-Object System.Management.Automation.Host.ChoiceDescription $key, $resultHash[$key]
}
$promptResponse = $host.ui.PromptForChoice($promptTitle, $promptMessage, $promptOptions, 0)
If I am understanding what you want correctly, this might be able to accomplish it for you.
If will gather a list of all the files in a folder, then get the content from each one and add them to an Array one by one.
[System.Collections.ArrayList]$Files = #(Get-ChildItem "C:\Logs\" |
Where-Object {$_.PSIsContainer -eq $false} |
Select-Object FullName)
[System.Collections.ArrayList]$List_Of_Commands = #()
foreach ($File in $Files) {
[System.Collections.ArrayList]$File_Contents = #(Get-Content $File.FullName)
foreach ($Content in $File_Contents) {
$Array_Object = [PSCustomObject]#{
'Command' = $Content
}
$List_Of_Commands.Add($Array_Object) | Out-Null
}
}
$List_Of_Commands

Resources