5
PowerShell
Idea shared by John Marx - 1/17/2022 at 8:00 PM
Proposed
I keep seeing a lot of questions on automating a lot of items. Many of us are pretty smart people. Microsoft Exchange integrates with PowerShell. I propose the following:

  • PowerShell be integrated and if it is already capable
  • Working samples that show us how to use for common tasks and then as questions come out in the forum integrate those answers into new PowerShell scripts

7 Replies

Reply to Thread
0
Tony Scholz Replied
Employee Post
Hello John, 

I currently use powershell with SmarterMail and SmarterTrack when doing simple operations leveraging the API. Once you get he basic authentication down the rest can be managed for any tasks you see fit. 

Is this the type of integration you are referring to? 

Thank you
Tony Scholz System/Network Administrator SmarterTools Inc. www.smartertools.com
1
Yes. But we need samples of basic operations. I know for one I would love basic ones like:

  • Creating a domain
  • Deleting a domain
  • Renaming a domain
  • Creating a user
  • Deleting a user
  • Renaming a user
  • Changing a user password
  • Changing a user setting (e.g., mailbox size)
  • Seeing when a user last logged in
  • Re-indexing
  • Backup
  • Setting TLS certificate
2
Zach Sylvester Replied
Employee Post
Hey John, 

I'm not sure if we have all of these examples written up. I have some examples here the only issue is it's in python. You can take a look at it and build your application based on these functions.

You can view the functions here. 
If you want me to add anything let me know and I can work on implementing it. 


Kind Regards, 



Zach Sylvester Software Developer SmarterTools Inc. www.smartertools.com
3
Tony Scholz Replied
Employee Post
Here is a quick example. 

Set up the connection details. 

# SERVER CONNECTION DETAILS
$API = @{};
$APIHost = 'localhost:9998';
$HTTPS = $false;
$API = @{ 
    'authUserName' = 'admin'
    'authPassword' = 'admin'
    'Method'       = 'POST'
    'ContentType'  = 'application/json'
    'URI'          = 'http' + $(if ($HTTPS -eq $true ) {'s'}) + '://' + $APIHost + '/'
};

I set up several functions that get used over and over. Here are the main ones

function UpdateURImethod ( $a, $b ) {  $API.uri = 'http' + $(if ($HTTPS -eq $true ) {'s'}) + '://' + $APIHost + '/' + $b; $API.Method = $a; }

function PrimaryAuth {
    $APIAuth = @{};
    $APIAuth = @{
        'Uri' = 'http' + $(if ($HTTPS -eq $true ) {'s'}) + '://' + $APIHost + '/api/v1/auth/authenticate-user';
        'Body' = '{"username":"' + $API.authUserName + '","password":"' + $API.authPassword + '","language":null,"twoFactorCode":""}';
        }; 
    $Auth = Invoke-RestMethod -Uri $APIAuth.Uri -ContentType $API.ContentType -Body $APIAuth.Body -Method $API.Method;

    # SERVER ADMIN AUTH TOCKEN 
    $API.Remove('Headers');
    $API.Add('Headers', @{ 'Authorization' = "Bearer $($Auth.accessToken)" });

    # REFRESH
    $API.Remove('Refresh');
    $API.Add('Refresh' , @{"token" = $($Auth.refreshToken)});

    # EXPERATION
    $API.Remove('accessTokenExpiration');
    [DateTime]$ATExp = $Auth.accessTokenExpiration;
    $API.Add('accessTokenExpiration', $ATExp);

    return $Auth;
};

function ImpersonateUser ($user_email) {
    $URI = $('http' + $(if ($HTTPS -eq $true ) {'s'}) + '://' + $APIHost + '/api/v1/settings/domain/impersonate-user/' + $user_email );
    $Impersonate = Invoke-RestMethod -Method POST -Uri $URI -ContentType $API.ContentType -Headers $API.Headers;

    # IMPERSONATE AUTH TOCKEN
    $API.Remove('HeaderImpersonate');
    $API.Add('HeaderImpersonate', @{ 'Authorization' = "Bearer $($Impersonate.impersonateAccessToken)" });
    $API.ImpersonateObject=$Impersonate;

    if ($API.ShowAuthData) {return $Impersonate;};
};

function ConnectPrimary ( $body ) { 
    if ( $body ) { 
        $call = Invoke-RestMethod -Uri $API.Uri -ContentType $API.ContentType -Body $body -Method $API.Method -Headers $API.Headers;
    } ELSE {
        $call = Invoke-RestMethod -Uri $API.Uri -ContentType $API.ContentType -Method $API.Method -Headers $API.Headers;
    };
    return $call; 
};

function ConnectImpersonate ( $body ) { 
    if ( $body ) { 
        $call = Invoke-RestMethod -Uri $API.Uri -ContentType $API.ContentType -Body $body -Method $API.Method -Headers $API.HeaderImpersonate;
    } ELSE {
        $call = Invoke-RestMethod -Uri $API.Uri -ContentType $API.ContentType -Method $API.Method -Headers $API.HeaderImpersonate;
    };
    return $call; 
};

Here is an example call grabbing a list of EAS ( ActiveSync ) accounts. 

PrimaryAuth;
UpdateURImethod 'GET' 'api/v1/settings/sysadmin/active-sync-mailboxes';
$EAS=ConnectPrimary;
$EAS.activeSyncAccounts;

Here is an example adding a new doamin

 PrimaryAuth

$dn = 'domain.tld';
$un = 'admin';
$pw = '12weDFGtr5^7yuhJU89';

UpdateURImethod 'POST' '/api/v1/settings/sysadmin/domain-put';
$b='{
    "domainData":{
        "name":"' + $dn + '",
        "path":"C:\\SmarterMail\\Domains\\' + $($dn).ToLower() + '",
        "hostname":"mail.' + $($dn).ToLower() + '",
        "isEnabled": true,
        "userLimit": 101,
        "aliasLimit": 101,
        "listLimit": 101,
        "maxSize": ' + $(1024 * 1024 * 5) + ',',#-> bytes * kilabytes * megabytes
        '"size": 123,
        "sizeMb": 135
    },
    "domainLocation":0,
    "domainLocationAddress":"",
    "deliverLocallyForExternalDomain":false,
    "adminUsername":"' + $($un).ToLower() + '",
    "adminPassword":"' + $($pw) + '"
}';

$results=ConnectPrimary $b;
$results; 

And an example adding a new user ( this API call is limited to domain admins )

 
PrimaryAuth;
ImpersonateUser 'admin@ascholz.local';
UpdateURImethod "POST" "api/v1/settings/domain/user-put" # Domain Admin Call

$u = "API";
$p = "12weDFGtr5^7yuhJU89";

$b = @('{
	"userData": {
		"userName": "' + $u + '",
		"password": "' + $p + '",
		"adUsername": null,
		"securityFlags": {
			"authType": 0,
			"authenticatingWindowsDomain": null,
			"isDomainAdmin": false
		},
		"isPasswordExpired": false
	}
}');

$newUser=ConnectImpersonate $b; 
$newUser;

I hope this helps you get started. 

Thank you
Tony Scholz System/Network Administrator SmarterTools Inc. www.smartertools.com
3
Tony Scholz Replied
Employee Post
Here are a few other examples from your list. Some of these calls are limited to domain admins, so I had to impersonate a domain admin first. 

# RENAME A DOMAIN

UpdateURImethod 'POST' 'api/v1/settings/sysadmin/rename-domain';
$renameBody='{"oldDomainName":"API-TESTING-DOMAIN.TLD","newDomainName":"domain.tld"}';
$results=ConnectPrimary $renameBody; 

# DELETE A DOMAIN

UpdateURImethod 'POST' 'api/v1/settings/sysadmin/domain-delete/domain.tld/true';
$results=ConnectPrimary;

# LIST USERS & GRAB LAST LOGIN TIME

ImpersonateUser 'admin@ascholz.local';
UpdateURImethod 'POST' 'api/v1/settings/domain/account-list-search'; 
$b = '{"skip":0,"take":"0","search":null,"sortField":"userName","sortDescending":false,"searchFlags":["users"]}';
$r = ConnectImpersonate $b;
$r.results|ft userName, lastLoginTime

# REINDEX USERS

ImpersonateUser 'admin@ascholz.local';
UpdateURImethod 'POST' 'api/v1/settings/domain/reindex-users';
$b='{"input":["2B","2FA","admin"]}';
$r = ConnectImpersonate $b; 

# REBUILD/RESTORE FOLDERS

function RestoreFolders ( $EMAIL, $FOLDER ) {
<# An authentication token is REQUIRED for this call. This call is limited to SYSTEM ADMINISTRATORS only. #>
    UpdateURImethod 'POST' 'api/v1/settings/sysadmin/restore-folders';
    $API_restore_body = "{'restorations':[{'folder':'" + $FOLDER + "','email':'" + $EMAIL + "','recursive':true}]}";
    ConnectPrimary $API_restore_body;
}; 


Thank you
Tony
Tony Scholz System/Network Administrator SmarterTools Inc. www.smartertools.com
0
Thank you. One I saw in another thread this would make everyone happy is the removal of a phishing email or other email. 
0
Thanks for your help

Reply to Thread