Office 365 Exchange Management Shell - Use data from Excel to run a loop with command - powershell

We are having round about 400 users that use Office 365 E-Mail Exchange which is managed on a local server via the Exchange Management Console. We activated E-Mail archives for the users that had PST-Files left on the server and migrated them by hand. To activate the mailbox archive we used the following command :
enable-remotemailbox <username> -archive
That worked fine and all. Now we want to double check and activate the archive for every user that has not been activated by hand. For this we have an excel sheet of all users with usernames which we want to run in a loop - so my question is :
Is it possible to tell the powershell to take information form an Excel/CSV file and loop through it with the above command (if an error occurs it needs to ignore and still run through). I imagined it somehow like
$users = Import-CSV C:\users.csv | foreach $user in $users
enable-remotemailbox $user -archive
Is it possible in this way or even an easier way?

You are almost there. Lets consider your CSV looks like this:
User
Alice
Bob
Then you can import the CSV and loop over each user using:
Import-Csv C:\users.csv | ForEach-Object {
enable-remotemailbox $_.User -archive
}

Related

Showing currently logged in user in a PowerShell running from a RMM Software as SYSTEM

i searched hours of my time and saw many ideas for this scenario but nothing worked for my like it should (i tested every code i saw on my own machine but nothing got me to the result i wanted.)
background: we are using a script in our RMM Software to Rename the Agents
$benutzer = [Environment]::UserName
Set-ItemProperty -Path "HKLM:\Software\MMSOFT Design\PC Monitor" -Name ComputerName -Value "$env:USERDOMAIN - $env:Computername - $benutzer"
This script gives us for the $env:USERNAME the user SYSTEM but we actually want the real USERNAME which is logged into this system.
Please help me out :)
The environment variable [System.Environment]::GetEnvironmentVariable('username') will give you the username for the executor of the script, in your case that is System because this is user who ran the code.
If you want to user the environment variable for the user, you must make it so the script been ran from or on behalf of the user, this also means that user must have "permissions" to modify the registry.
If I understand right, you need to know who is the "Logged in user" for the machine where that script runs, unfortunately there is nothing available from PowerShell that do that to my knowledge, instead you could use the build-in tool query for Windows machines, which will provide you with a list with all logged in users to that machine, you would need to further test it to get what you want from it, the output looks like this :
PS C:\Users\t-user> query user
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
>t-user console 1 Active none 8/29/2022 11:58 AM
The trick with query user is that it will provide you with the list of users in case more than one have logged in.
I see what you are trying to do, and here is a "dirty" example of doing it :
$loggedUserList= query user
if($loggedUserList.count -eq 2){
$user = $loggedUserList -split ">" -replace '\s\s+', ';' | convertfrom-csv -Delimiter ';' | select -ExpandProperty username
Write-Host "Logged in user is - $user"
}else{
Write-Host "More than one user have signed"
}

Script to log on with ssh and report back on success

I want to make a script that uses SSH to log into our various servers. The script should try to log into a list of machines with a default user to check if theres default passwords that need to be changed or other securtiy flaws that allow any user to log on. On success of logging in, it should send an email or similiar to let me know it found something.
Below is what I got so far. Is that a correct start? For some reason it fails to get the right client name from the textfile - I used a similiar looking script to get usernames and AD attributes and it worked there. I already got PoSH-SSH installed and it works when I manually invoke a connection.
Once that works I need a if/else that does something on a successfull login. How would I do that? What condition can I use to check if its successful or not?
thank you!
$clients = Get-Content C:\clients.txt
$List = ForEach ($client in $clients){
New-SSHSession -$client -Credential test
}
$List | Export-Csv C:\clients.csv -NoTypeInformation

Why does Enable-Mailbox show all mailbox properties when finished?

I have a Powershell script that creates AD Users from a CSV file and creates a mailbox in our on-premises Exchange server. The script works well, but every time it finishes the 'Enable-Mailbox' command, it outputs the mailbox properties as if 'Get-Mailbox | FL' is being called. The command is used as follows:
Enable-Mailbox -Identity <identity> -Alias <alias> -Database <database>
This link says that Enable-Mailbox has no output (https://learn.microsoft.com/en-us/exchange/client-developer/management/exchange-management-shell-cmdlet-input-and-output-types), and this command is at the end of the loop, so nothing else would be outputting anything before moving on to the next user.
Can anyone shed some light on what's going on or point me in the direction to figure out why this is happening?
EDIT: I'm piping to Out-Null to suppress the output for now

Using Read-Host to output information from a script

I am trying to run a script against exchange to bring back all of the mailboxes a certain user has access to. I want to be able to input the usersname using read-host. I currently have this:
$username = Read-Host("Please enter users username")
#Enable Exchange cmdlets
add-pssnapin *exchange* -erroraction SilentlyContinue
Get-MailBox | Get-MailboxPermission -User $username | FL > C:\MailboxPermissions.txt
However, when I run this via powershell, it asks for the username, looks like it is starting to run the script, then powershell just exits and there is not data outputted
Any help would be greatly appreciated
Thanks for all the help
I finally figured it out and there were a couple of issues. It was to do with the result size. I added -resultsize unlimited:
$username = Read-Host("Please enter users username")
add-pssnapin *exchange* -erroraction SilentlyContinue
>Get-MailBox -resultsize unlimited | Get-MailboxPermission -User $username | FL > C:\MailboxPermissions.txt
It would also not work by running the .ps1 file as this was not run by admin, and it needs admin permissions to output to the location I want. Once I created a shortcut for it to run via the powershell.exe with admin credentials it is now working as expected.
The problem is that you are only out putting to the screen.
This means that when you run your script it will carry out the required action, print to screen and close the window immidiatly. In turn, this means you can't see the output.
As #DarkLite1 mentioned, you could output to a file.
Or, you could simply allow the console to wait before closing. This is done like this at the end of your code:
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
You may also need a Write-Host on the last action in your code snippet, I'm not entirely sure as I am not familiar with how Get-Mailbox works, but try it without first.
To summarize, You must keep the window open or print the results to file to actually see anything. The code you have currently will complete so fast you will never see any output.

Powershell: Re-create RDS Remote Apps by Looping?

I'm stumped. I can usually take the output of one powershell command and use it as the input to another powershell command. For example:
Get-Mailbox | Set-Mailbox -MaxSendSize 40MB
This will loop through every mailbox and then set the maximum send size to 40 MB in Exchange 2007.
...but the same doesn't work with get-rdremoteapp and new-rdremoteapp.
Get-RDRemoteApp | new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local
The goal of this command is that we are preparing to Migrate from a Windows 2012 RDS environment on virtual servers to a Windows 2012 R2 environment on physical servers.
On the virtual 'edge' server, I should be able to get all the RD Remote Apps, loop through them, and then use the 'new-rdremoteapp' command to create them on the new 'edge-1' server.
What actually happens is the command runs and creates the 1st remote app, then exits without an error. It doesn't process the apps in the list.
I think I need to use foreach-object, but after reading the docs and playing around, I can't seem to get it to work.
I couldn't find an easy out. I had to specify a bunch of parameters like so:
Get-RDRemoteApp | foreach-object -process {new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local -displayname $_.displayname -filepath $_.filepath -alias $_.alias -commandlinesetting $_.commandlinesetting -usergroups $_.usergroups}
Time to find a job that has more bash scripting... ;)