Powershell Help to compare - azure-powershell

Hope you all are safe and well !!
I am running a script that gives me Azure AD apps with its secret end date property. The property name which gives me all details in Azure AD is “PasswordCredentials” and I am using get-azureadapplication cmdlet.
What is the best way to check If the app has end date value within a month and filter on it, I tried where-object with get-date.adddays(30) and tried to compare with -lt operators.
Appreciate your support here.

Well, in your case, you should note there may be several PasswordCredentials for one app, so you need to use a loop to check every PasswordCredential.
And the EndDate you got from the Get-AzureADApplication command is a UTC time, but Get-Date returns the local time, so you need to use (Get-Date).AddDays(30).ToUniversalTime() instead of (Get-Date).AddDays(30). Also, if you just want to check the expiring ones, you must exclude the ones that have expired, so use $PasswordCredential.EndDate -gt $nowdate like below.
As you did not give your script, I can just give a sample for you, my sample is for a single app, if you want to check all the apps in your tenant, use a loop to do that.
$PasswordCredentials = (Get-AzureADApplication -ObjectId <object-id>).PasswordCredentials
$nowdate = (Get-Date).ToUniversalTime()
$wantdate = (Get-Date).AddDays(30).ToUniversalTime()
foreach($PasswordCredential in $PasswordCredentials){
if($PasswordCredential.EndDate -lt $wantdate -and $PasswordCredential.EndDate -gt $nowdate){
$keyid = $PasswordCredential.KeyId
Write-Output "The key with KeyId $keyid will expire"
}
}
Update:
If you want to get the AppId and AppName, you could use the script below.
$apps = Get-AzureADApplication -All $true
$nowdate = (Get-Date).ToUniversalTime()
$wantdate = (Get-Date).AddDays(30).ToUniversalTime()
foreach($app in $apps){
$PasswordCredentials = $app.PasswordCredentials
$appid = $app.AppId
$displayname = $app.DisplayName
foreach($PasswordCredential in $PasswordCredentials){
if($PasswordCredential.EndDate -lt $wantdate -and $PasswordCredential.EndDate -gt $nowdate){
$a = $app | select #{Name="AppId"; Expression={$appid}}, #{Name="DisplayName"; Expression={$displayname}}, #{Name="EndDate"; Expression={$PasswordCredential.EndDate}}
Write-Output $a
}
}
}

Related

VB.net and powershell variables

I have a Visual Studio form running with VB.net and I'm collecting info needed to setup an AD user. In the end, this info will need to simply be passed to Powershell with no return info needed. Before that though, I need it to check if a printer code has already been assigned to someone before allowing it to be submitted to another user. I have a simple powershell script written up for it.
(We use the Pager field to store the printer code.)
Import-Module ActiveDirectory
$Page = $args[0]
Get-ADUser -Filter { Pager -like $Page } | FT Name
I setup the code I found HERE, and attempted to modify it to my script but it keeps crashing on
Dim results As Collection(Of PSObject) = MyPipeline.Invoke()
It gives me: An unhandled exception of type 'System.Management.Automation.ParseException' occurred in System.Management.Automation.dll
If I run his little 6+5 basic example script, it works, but when I try to retrieve info and return a name, it doesn't like it. How can I get it to return the name of the person if it find it? And since it won't run, I'm not even sure if passing the printer code as $args[0] is going to work yet.
Your results is expecting a collection of PowerShell objects. When you pipe the Get-ADUser command to Format-Table, it effectively strips the object down to a stream of strings. Try without the | FT Name.
Import-Module ActiveDirectory #if you're using powershell 3 or later, this may be redundant
# $Page = $args[0] # don't need to do this
$results = Get-ADUser -Filter { Pager -like $args[0] }
Write-Verbose $results
#Write-Verbose $results.Name #try this if the above one works
Update:
Write-Verbose may be causing an issue.
Try this:
Get-ADUser -Filter { Pager -like $args[0] }
Just that one line as the total PS code. (Assuming you have PowerShell 3.0 or later, you don't need Import-Module) That line will return objects of type TypeName: Microsoft.ActiveDirectory.Management.ADUser (from `Get-ADUser username | Get-Member).
You may also be able to use the .Net object type directly, without PowerShell. I'm not knowledgeable about .NET beyond what I picked up working with PowerShell.
Accessing AD using .NET, info from MSDN.

Powershell copy file with variable

I'm trying to run the following script that I thought was quite simple. What am I doing wring here...
[Environment]::UserName = $username
Write-Host "The user is $username"
$from = "c:\Users\" + $username + "\favourites\*.*"
$to = "c:\test"
Write-Host "This is from dir: $from"
Write-Host "This is to dir: $to"
Copy-Item $from $to
The script does not seem to like the + $username + ...
I think you got your first line the wrong way around. Currently you're assigning an empty variable (value of it should be $null) to $Env:UserName, thus overwriting the username, not reading it.
I think it should be
$username = [Environment]::Username
or, as noted above, you can access environment variables via the special Env: drive:
$username = $Env:Username
And unrelated to your problem, just a matter of nicer code:
You can put the username directly into the string (which you seem to know, as demonstrated a line above – where you don't need a string in this case, though):
$from = "C:\Users\$username\favourites\*"
You don't need to fetch the user name at all, you can use
$Env:UserProfile
or
[Environment]::GetFolderPath([Environment+SpecialFolder]::UserProfile)
or even
[Environment]::GetFolderPath([Environment+SpecialFolder]::Favorites)
which might ultimately be what you're after, here.

How to search with multiple keys in a hash table in powershell

I'm writing a Powershell script and in it I'm using a hash table to store information about database checks. The table has 5 keys (host, check, last execution time, last rep, status) and I want to search in my table for values where:
$s = $table where $host -eq $hostname -and check -eq $check
Does anyone have any idea how this is done? And if it makes any difference, the script cannot rely on .NET framework higher than 2.0
I´m new to Powershell and scripting in general so this might be very obvious but I still can't seem to find an answer on Google. Also if someone knows a good reference page for Powershell scripting I would really appreciate a link.
Gísli
EDIT: Don't see how it matters but here is a function I use to create a hash table:
function read_saved_state{
$state = #{}
$logpos = #{}
$last_log_rotate = 0
foreach($s in Get-Content $saved_state_file){
$x = $s.split('|')
if($x[0] -eq 'check'){
$state.host = $x[1]
$state.check = $x[2]
$state.lastexec = $x[3]
$state.lastrep = $x[4]
$state.status = $x[5]
}
elseif($x[0] -eq 'lastrotate'){
$last_log_rotate = $x[1]
}
elseif($x[0] -eq 'log'){
$logpos.lastpos = $x[3]
}
}
$saved_state_file has one line for each check run and can also have a line for last log rotate and last log position. There can be as many as 12 checks for one host.
I'm trying to extract a particular check, run at a particular host, and changing the lastexec_time, last_rep and status.
return $state,$logpos,$last_log_rotate
}
Assuming you have an array or list of hashtables (not entirely clear from the question), your syntax is pretty close:
$s = $tables | where {($_.host -eq $hostname) -and ($_.check -eq $check)}

How do I manipulate data out of a variable in powershell

I have a power-shell script with which I am trying to back up a constantly changing number of SQL databases. Fortunately all of these databases are listed in a registry key. I am leveraging this in a for-each loop. The issue that I am having is that after grabbing the registry value that I want, when I try to pass it into my function to back up the databases there seems to be information in the variable that I can get rid of. If I output the contents of the variable to the screen by just calling the variable ($variable) is shows just fine. But if I write-host the variable to the screen the extra "content" that shows up when calling the function also shows up.
Here is the part of the script that generates the contents of the variable.
foreach ($childitem in get-childitem "HKLM:\SOFTWARE\Wow6432Node\Lanovation\Prism Deploy\Server Channels")
{$DBName = get-itemproperty Registry::$childitem | select "Channel Database Name"
write-host $DBname}
Here is what write-host displays :
#{Channel Database Name=Prism_Deploy_Sample_268CBD61_AC9E_4853_83DE_E161C72458DE}
but what I need is only this part :
Prism_Deploy_Sample_268CBD61_AC9E_4853_83DE_E161C72458DE
I have tried looking online at how to do this, and what I've found mentions things similar to $variable.split and then specifying my delimiters. But when I try this I get an error saying "Method invocation failed because [System.Management.Automation.PSCustomObject] doesn't contain a method named 'split'."
I'm at a loss as to where to go from where I'm at currently.
select-object will return an object that has the named properties that you "select". To get just value of that property, just access it by name:
write-host $DBname."Channel Database Name"
Sounds like it's returning a hash table row object.
Try
write-host $DBName.value
or, failing that, do a
$DBName | Get-member
When in doubt, get-member gives you a nice idea of what you are dealing with.
You should be able to write
foreach ($childitem in get-childitem "HKLM:\SOFTWARE\Wow6432Node\Lanovation\Prism Deploy\Server Channels")
{$DBName = get-itemproperty Registry::$childitem | select "Channel Database Name"
write-host $DBname.Name}
to get what you are looking for

How to use a PowerShell variable as command parameter?

I'm trying to use a variable as a command's parameter but can't quite figure it out. Let's say MyCommand will accept two parameters: option1 and option2 and they accept boolean values. How would I use $newVar to substitute option 1 or 2? For example:
$newVar = "option1"
MyCommand -$newVar:$true
I keep getting something along the lines of 'A positional parameter cannot be found that accepts argument '-System.String option1'.
More Specifically:
Here, the CSV file is an output of a different policy. The loop goes through each property in the file and sets that value in my policy asdf; so -$_.name:$_.value should substitute as -AllowBluetooth:true.
Import-Csv $file | foreach-object {
$_.psobject.properties | where-object {
# for testing I'm limiting this to 'AllowBluetooth' option
if($_.name -eq "AllowBluetooth"){
Set-ActiveSyncMailboxPolicy -Identity "asdf" -$_.name:$_.value
}}
}
Typically to use a variable to populate cmdlet parameters, you'd use a hash table variable, and splat it, using #
$newVar = #{option1 = $true}
mycommand #newVar
Added example:
$AS_policy1 = #{
Identity = "asdf"
AllowBluetooth = $true
}
Set-ActiveSyncMailboxPolicy #AS_policy1
See if this works for you:
iex "MyCommand -$($newVar):$true"
I had the same Problem and just found out how to resolve it. Solution is to use invoke-Expression: invoke-Expression $mycmd
This uses the $mycmd-string, replaces variables and executes it as cmdlet with given parameters
Nowadays, If you don't mind evaluating strings as commands, you may use Invoke-Expression:
$mycmd = "MyCommand -$($newVar):$true"
Invoke-Expression $mycmd
I would try with:
$mycmd = "MyCommand -$($newVar):$true"
& $mycmd
result
Can't work because the ampersand operator just execute single commands without prameters, or script blocks.