I'm new to powershell and have been practicing to get better so would greatly appreciate all your help.
I have a txt file with just a list of servers that I need to add an account to. However, I need to exclude the server names that does not contain "-" in the servername.
This is what I have right now which obviously doesn't work and I keep getting errors.
$servers = Get-Content "$PSScriptRoot\SQLServers.txt"
foreach ($server in $servers| Where $server -contains "*-*" )
For a wildcard string comparison, you'll want the -like operator, and then refer to the current pipeline item being tested by Where-Object with $_:
foreach ($server in $servers |Where { $_ -like "*-*" }) {
# work with each matching $server here
}
-like can also be used to filter a collection of strings directly, so in your case you could do:
foreach ($server in #($servers) -like "*-*") {
# work with each matching $server here
}
If your file have only one column you can use import csv and directly set the name of one and uniq colum, like this :
Import-Csv "$PSScriptRoot\SQLServers.txt" -Header server | where server -Like "*-*" | foreach{
#user serveur name here
$_.Server
}
Otherwise you can directly filter on $_ variable like this :
Get-Content "$PSScriptRoot\SQLServers.txt" | where {$_ -like "*-*"} | foreach{
#user serveur name here
$_
}
Related
I am trying to append to a group display name unless the append already exists currently my code is as below and it works on the first pass but if you re run it it appends the text each time again.
I would like a way to check if the "-Yammer" already exists in display name and skip if it does.
Any clever ways of achieving this ?
Many Thanks
Get-UnifiedGroup -ResultSize Unlimited |?{$_.GroupSku -eq "Yammer"} | Export-Csv "C:\Temp\yammerGroup.csv" -NoTypeInformation
Import-CSV "C:\Temp\yammerGroup.csv" | ForEach-Object {
Set-UnifiedGroup -Identity $_.id -DisplayName ($_.DisplayName + "-Yammer")}
{
Set-UnifiedGroup -Identity $_.id -HiddenFromAddressListsEnabled $False}
You can use an if statement with the EndsWith method to check if the end of the group name matches your specified string.
Note EndsWith is case-sensitive, so I've also added ToLower to convert the group name to lower-case first.
Import-CSV "C:\Temp\yammerGroup.csv" | ForEach-Object {
if (! ($_.DisplayName.ToLower().EndsWith("-yammer") ) )
{
Set-UnifiedGroup -Identity $_.id -DisplayName ($_.DisplayName + "-Yammer")
}
}
I got a small issue. I have a CSV with some names. I needed to get the email addresses of those users, so I created a small script that will find users with that firstname and lastname in AD.
After that, I wanted to export it to a new CSV file, but keep the phone-numbers from the first CSV file so its also available in the new CSV export.
That last part don't seem to work. In the output that expression is shown as {}.
Can someone help me?
$csv = import-csv -path C:\users\da6\desktop\UsersZonderEmail.csv
$output = #()
foreach ($i in $csv) {
$givenname = $i.Voornaam
$lastname = $i.Achternaam
$number = $i.IpPhone
$output += try {Get-ADUser -Filter {givenname -eq $givenname -and surname -eq $lastname} | select Name, UserPrincipalName, #{ name="ipphone"; expression=$number}} catch {}
}
Basically what is wrong with your code is that you forgot the opening bracket { in the expression oart of the calculated property.
Also note that -Filter should be a string, not a scriptblock.
Lastly, adding to an array with += is a bad habit, as the entire array needs to be rebuilt in memory on every addition.
Better let PowerShell collect the values from the loop:
$csv = Import-Csv -Path 'C:\users\da6\desktop\UsersZonderEmail.csv'
$output = foreach ($item in $csv) {
Get-ADUser -Filter "GivenName -eq '$($item.Voornaam)' -and Surname -eq '$($item.Achternaam)'" -Properties EmailAddress |
Select-Object Name, UserPrincipalName, #{ Name="ipphone"; Expression = {$item.IpPhone}}, EmailAddress
}
# output to new CSV file
$output | Export-Csv -Path 'C:\users\da6\desktop\UsersMetEmail.csv' -NoTypeInformation
What I want to find out if I can do, is splatting in a Where-Object clause or something similar. I know you can do this with parameters already.
I am trying to filter out multiple values from one property using -notlike.
I have looked at https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-5.1 but nothing is mentioned in here.
An example of what I'm currently trying to do:
$allUsers | Where-Object {($_.UserPrincipalName -notlike "Health*") -and ($_.UserPrincipalName -notlike "admin*")}
I am trying to do it this way as there are lots of accounts I want to exclude that contain the the word "admin" in their UPN. Unfortunately there is a long list of what I need to exclude, as I am running through a cleanup process.
I have been suggested to use an array of exclusions and then try using -notcontains or -notin but this has not worked for me, I'm assuming because I need it to be wildcard friendly.
I think it is a lot easier to use the regex -notmatch operator:
# create a regular expression string by combining the keywords with the OR '|' character
$exclude = ('test','admin','health' | ForEach-Object { [regex]::Escape($_) }) -join '|'
# get all users except the users that have any of the keywords in their UserPrincipalName
Get-ADUser -Filter * | Where-Object { $_.UserPrincipalName -notmatch $exclude }
You can do the following to build a dynamic filter by just comma-separating your exclusion strings, which effectively creates an array of strings ($Exclusions).
$Exclusions = 'Health*','admin*'
$FilterArray = $Exclusions | Foreach-Object {
"UserPrincipalName -notlike '$_'"
}
$Filter = #{'Filter' = "{0}" -f ($FilterArray -join " -and ")}
Get-ADUser #Filter
-notin works fine for me, maybe supply a bit more of your data in your question to see what you;re trying to filter out? Is it the wildcards causing an issue?
$listofexclusions = #("userid1","userid2")
Get-ADUser -Filter * | Where-Object { $_.SamAccountName -notin $listofexclusions } | Select Name,SamAccountName | ft
Edit:
If you need wildcards, there are some previous threads about this here
If you're using something like Get-ADUser you can do what other answers have suggested and let the cmdlet filter the results for you using its built in functionality.
However, if you just want to apply a bunch of -like operations to a collection of objects you can write your own Test-LikeAny function as follows:
function Test-LikeAny
{
param( [string] $value, [string[]] $patterns )
foreach( $pattern in $patterns )
{
if( $value -like $pattern )
{
return $true
}
}
return $false
}
and then you can use it like this:
$values = #(
(new-object pscustomobject #{ "Property1" = "...value1..." }),
(new-object pscustomobject #{ "Property1" = "...value2..." }),
(new-object pscustomobject #{ "Property1" = "...value3..." })
)
$patterns = #( "*value1*", "*value2*" )
$values | Where-Object { -not (Test-LikeAny $_.Property1 $patterns) }
which gives:
Name Value
---- -----
Property1 ...value3...
I can't seem to figure out how to use a variable in a herestring, and for the variable to be expanded at a later time in a piped command. I have experimented with single ' and double " quotes, and escape ` characters.
I am trying to use the herestring for a list (e.g. like an array) of Exchange groups, and a corresponding list of conditions to apply to those groups. Here is a simplified example which fails to use the $Conditions variable correctly (it does not expand the $_.customattribute2 variable):
# List of groups and conditions (tab delimitered)
$records = #"
Group1 {$_.customattribute2 -Like '*Sales*'}
Group2 {$_.customattribute2 -Like '*Marketing*' -OR $_.customattribute2 -Eq 'CEO'}
"#
# Loop through each line in $records and find mailboxes that match $conditions
foreach ($record in $records -split "`n") {
($DGroup,$Conditions) = $record -split "`t"
$MailboxList = Get-Mailbox -ResultSize Unlimited
$MailboxList | where $Conditions
}
No, no that's not going to work. The whole good bit about PowerShell is not having to make everything a string and then drag it to the moon and back trying to get the important stuff back out of the string. {$_.x -eq "y"} is a scriptblock. It's a thing by itself, you don't need to put it in a string.
#Array of arrays. Pairs of groups and conditions
[Array]$records = #(
('Group1', {$_.customattribute2 -Like '*Sales*'}),
('Group2', {$_.customattribute2 -Like '*Marketing*' -OR $_.customattribute2 -Eq 'CEO'})
)
#Loop through each line in $records and find mailboxes that match $conditions
foreach ($pair in $records) {
$DGroup, $Condition = $pair
$MailboxList = Get-Mailbox -ResultSize Unlimited
$MailboxList | where $Condition
}
TessellatingHeckler's explanation is right. However, if you insist on herestring, it's possible as well. See the following example (created merely for demonstration):
$records=#'
Group1 {$_.Extension -Like "*x*" -and $_.Name -Like "m*"}
Group2 {$_.Extension -Like "*p*" -and $_.Name -Like "t*"}
'#
foreach ($record in $records -split "`n") {
($DGroup,$Conditions) = $record -split "`t"
"`r`n{0}={1}" -f $DGroup,$Conditions
(Get-ChildItem |
Where-Object { . (Invoke-Expression $Conditions) }).Name
}
Output:
PS D:\PShell> D:\PShell\SO\47108347.ps1
Group1={$_.Extension -Like "*x*" -and $_.Name -Like "m*"}
myfiles.txt
Group2={$_.Extension -Like "*p*" -and $_.Name -Like "t*"}
Tabulka stupnic.pdf
ttc.ps1
PS D:\PShell>
Caution: some text/code editors could convert tabulators to space sequences!
I need some help writing a script as i am struggling to understand the logic.
I basically have a list of user ids that i need to check to see if they have two certain AD groups. If they have, these need to be outputted into a csv and highlighted.
Can anyone help to get me started? I need to use the Quest Powershell cmdlets
Here is the code
$textFileContents = Get-Content C:\temp\powershell\users.txt
$results = #()
foreach($username in $textFileContents){
$groups = get-qaduser $username |select -expand memberof
if ($groups -match "grpuip1" -and $groups -match "group2"){
echo $group
}
}
check this to begin :
"user1","user2" | foreach {
$groups = get-qaduser $_ |select -expand memberof
if ($groups -match "GROUP1" -and $groups -match "GROUP2"){
echo $_
}
}
I'd use the cmdlet Get-QADMemberOf instead of Get-QADUser. There's nothing wrong with what you're doing, but it's retrieving more information than you need.
Try this to start with:
$textFileContents = Get-Content C:\temp\powershell\users.txt
# Rather than initializing the array, and adding new elements,
# just output each element of the loop to the pipeline, and
# assign the results of the whole pipeline to the variable.
# This is *much* faster than adding to an array
$results = $textFileContents | ForEach-Object {
$userGroups = Get-QADMemberOf $_
if ($userGroups -contains "group1" -and $userGroups -contains "group2") {
New-Object -TypeName PSObject -Property #{"UserName" = $_; "Groups" = ($userGroups -join ",");}
}
}
$results | ConvertTo-Csv -NoTypeInformation | Set-Content C:\Filename.txt