We needed to test TrueNAS and decided to use Powershell and TrueNAS API on two VMware VMs.
Tested on:
Windows 11 Pro v22H2 (OS Build 22621.3593)
Powershell 5.1.22621.2506
TrueNAS Scale Dragonfish-24.04.1 on VMware
Here’s the script if anyone wants to check it out.
<#
Purpose:
Test provisioning TrueNAS with Powershell/TrueNAS API
Reasoning:
If SMB is needed, Windows is used in the environment and powershell is available
Tested on:
Windows 11 Pro v22H2 (OS Build 22621.3593)
Powershell 5.1.22621.2506
TrueNAS Scale Dragonfish-24.04.1 on VMware
Overview
Setup two TrueNAS Scale systems with 1-way PUSH replication
Details
Configure TrueNAS Scale "TN1"
Set DNS,Hostname, Domain name, Netbios name, NTP
Create RAID Z1 Pool with all available disks
Create Datset for SMB share
SMB Share / SBM Share Group and User / Set SMB Service to autostart on reboots
Enable snapshots
Enable PUSH replication to TN2 (after configuring TN2)
Configure TrueNAS Scale "TN2" with
Set DNS,Hostname, Domain name, Netbios name, NTP
Create RAID Z1 Pool with all available disks
Your responsibility
Do not test in production
Change passwords and apikeys after testing
Better yet, destory the test TrueNAS systems and re-use anything of value from this example
How to get started
Prerequisites
1. Two systems with fresh install of TrueNAS Scale (VM or baremetal)
installing TrueNAS is outside the scope
TrueNAS Scale download: https://www.TrueNAS.com/download-truenas-scale/
2. IP address of each is pingable from where powershell will run
3. Each system needs 3 or more unused drives to create the pool
4. Script will be run in Powershell ISE
Steps to configure TrueNAS Scale
1. Create the apikey on each system
a. Log into the first TrueNAS SCALE system as admin using your browser
b. In the top right corner, click "admin", then click "API Keys"
c. Click "Add", type "admin_apikey", click "Save"
d. Click "Copy To Clipboard" to copy the newly created "API Key" and save it somewhere, we will need it.
Note: if you lose it API Key, deleted it and re-create it
e: do the same thing for the second TrueNAS Scale system
2. Set the ip address and apikey for each TrueNAS Scale system
a. search for $Script:TN1_name set the ip address for the first TrueNAS Scale system
b. search for $Script:TN1_apikey set the apikey for the first TrueNAS Scale system
c. search for $Script:TN2_name set the ip address for the second TrueNAS Scale system
d. search for $Script:TN2_apikey set the apikey for the second TrueNAS Scale system
e: review the rest of the variables but only modify if you are confident in the changes
f: note: in the real world you will encrypt the API keys, for testing they are clear text
3. Save the changes and run the entire script in Powershell ISE to load variables and functions
4. Test API Access
highlight/select "BasicInfo -TN tn1" below and "Run Selection" or hit F8
This should return several lines and no error
you can also copy "BasicInfo -TN tn1", paste in the console and hit enter (no quotes when copying)
do the same with "BasicInfo -TN tn2"
BasicInfo -TN tn1
BasicInfo -TN tn2
If you receive errors, do not proceed since API access is not working. Troubleshooting needed.
5. Configure first TrueNAS Scale system
Higilight/select each line below and run with F8 or copy/paste in the console and hit enter
Suggestion: do one line at a time instead of all at once
SetDNS -TN tn1
SetHostName -TN tn1
SetDomainName -TN tn1
UpdateSmbNetbios -TN tn1
SetNtpServers -TN tn1
SetSnmpService -TN tn1
CreateZ1Pool -TN tn1
CreateGroupAndUserForSmb -TN tn1
CreateDatasetForSmbShare -TN tn1
CreateSmbShare -TN tn1
SetSmbAcl -TN tn1
SetSmbServiceAutostart -TN tn1
EnabledSmbSnapshots-every5min-keep24hours -TN tn1
EnabledSmbSnapshots-every8hours-keep7days -TN tn1
ShowSnapshotTasks -TN tn1
DisableHttpRedirect -TN tn1
SetupSShConnection -TN tn1
ListAllKeychainCredentials -tn "tn1"
CreateReplicationTasksForSnapshots -sourceTN "tn1" -targetTN "tn2"
#EnableHttpRedirect -TN tn1
#target for replicaiton needs to be configured below
6. Configure second TrueNAS Scale system
Higilight/select each line below and run with F8 or copy/paste in the console and hit enter
Suggestion: do one line at a time instead of all at once
SetDNS -TN tn2
SetHostName -TN tn2
SetDomainName -TN tn2
UpdateSmbNetbios -TN tn2
SetNtpServers -TN tn2
SetSnmpService -TN tn2
CreateZ1Pool -TN tn2
##########
# -> wait 5 minutes for replication from tn1 to create the dataset repl-WinShare1 on tn2
# -> URL: http://{tn2 ip address}/ui/datasets/test-z1-pool
##########
CreateGroupAndUserForSmb -TN tn2
CreateSmbShare -TN tn2
#SetSmbAcl -TN tn2
SetSmbServiceAutostart -TN tn2
7. Access the shares
Username: will
Password: password
truenas1: \\{ip of truenas system 1}\winshare1
truenas1: \\{ip of truenas system 2}\repl-winshare2
#>
<#
https://{ip of TrueNAS}/ui/system/general -> Gui -> Web Interface HTTP -> HTTPS Redirect: Disabled
#>
##########################
#### script variables ####
##########################
$Script:TN1_name = "0.0.0.0" # change to first TrueNAS scale ip or dns name
$Script:TN1_apikey = "" # change to apikey of first TrueNAS scale
$Script:TN1_hostname = "TEST-TN-01"
$Script:TN2_name = "0.0.0.0" # change to second TrueNAS scale ip or dns name
$Script:TN2_apikey = "" # change to apikey of second TrueNAS scale
$Script:TN2_hostname = "TEST-TN-02"
$Script:TN1_DNS1 = "8.8.8.8" #Google Primary DNS
$Script:TN1_DNS2 = "8.8.4.4" #Google Secondary
$Script:TN1_DNS3 = "9.9.9.9" #Quad9 Primary
$Script:TN2_DNS1 = "8.8.8.8" #Google Primary DNS
$Script:TN2_DNS2 = "8.8.4.4" #Google Secondary
$Script:TN2_DNS3 = "9.9.9.9" #Quad9 Primary
$Script:TN1_NTP1 = "0.debian.pool.ntp.org" #TrueNAS NTP Default
$Script:TN1_NTP2 = "1.debian.pool.ntp.org" #TrueNAS NTP Default
$Script:TN1_NTP3 = "2.debian.pool.ntp.org" #TrueNAS NTP Default
$Script:TN2_NTP1 = "0.debian.pool.ntp.org" #TrueNAS NTP Default
$Script:TN2_NTP2 = "1.debian.pool.ntp.org" #TrueNAS NTP Default
$Script:TN2_NTP3 = "2.debian.pool.ntp.org" #TrueNAS NTP Default
$Script:SnmpRo = "public" #readonly snmp community name
$Script:SnmpEnable = $true
$Script:ReplicationPrependText = "repl-"
$Script:TN1_ReplicationAccount = $Script:TN1_hostname + "_Replication"
$Script:TN1_ReplicationPassword = "password"
$Script:TN2_ReplicationAccount = $Script:TN2_hostname + "_Replication"
$Script:TN2_ReplicationPassword = "password"
$Script:TN1_WindowsShareName = "WinShare1"
$Script:TN1_WindowsShareGroup = "WinShare1"
$Script:TN1_WindowsShareReadOnly = $false
$Script:TN2_WindowsShareName = $ReplicationPrependText + "WinShare1"
$Script:TN2_WindowsShareGroup = $ReplicationPrependText + "WinShare1"
$Script:TN2_WindowsShareReadOnly = $true
#keeping usernames and password consistent
$Script:WindowsShareUser1Username = "Will"
$Script:WindowsShareUser1FullName = "Will Neverknow"
$Script:WindowsShareUser1Password = "password" #for testing only
$Script:DomainName = "contoso.com"
$Script:PoolName = "test-z1-pool"
$Script:RaidType = "RAIDZ1"
$Script:JsonColor = "Cyan"
$Script:ShowUrlInfo = $true #show URL/Method/Json
$Script:BarLength = 80 #number of characters in separation bar
$Script:BarChar = "V" #character for separation bar
$Script:BarColor = "Gray"
Function Invoke-TrueNASAPI {
param (
[string] $tn,
[string] $method,
[string] $url,
[object] $body = $null
)
if ($tn -eq $null) {Write-Output "TN parameter missing. Exiting."; Start-Sleep -Seconds 5 ;break}
$apiKey = Get-Variable -Name "${TN}_apikey" -ValueOnly
$apiUrltemp = Get-Variable -Name "${TN}_name" -ValueOnly
$apiUrl = "https://" + $apiUrltemp + "/api/v2.0"
$headers = New-Object System.Net.WebHeaderCollection
$headers = @{
accept="*/*"
Authorization="Bearer $apiKey"
}
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$contentType = "application/json"
if ($ShowUrlInfo) {
Write-Host $($BarChar * $BarLength) -ForegroundColor $BarColor
Write-Host "URL: $apiUrl/$url" -ForegroundColor $JsonColor
Write-Host "Method: $method" -ForegroundColor $JsonColor
if ($body -ne $null) {
Write-Host "JSON" -ForegroundColor $JsonColor
Write-Host "$body" -ForegroundColor $JsonColor
}
}
#where the magic happens
$result = Invoke-RestMethod -Uri "$apiUrl/$url" -Method $method -Headers $headers -UseBasicParsing -ContentType $contentType -Body $body
$result
}
Function BasicInfo{
param ([string] $tn)
Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/info"
$apiUrltemp = Get-Variable -Name "${TN}_name" -ValueOnly
$apiUrl = "http://" + $apiUrltemp + "/api/docs/"
Write-Host "Local API URL [$apiUrl] -> Click RESTful 2.0" -ForegroundColor $JsonColor
write-host "TrueNAS RESTful API [https://www.truenas.com/docs/api/scale_rest_api.html]"
}
Function GetInfo{
param ([string] $tn)
Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/info"
Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/hostname"
Invoke-TrueNASAPI -TN $tn -Method Get -Url "network/configuration"
# Get information on all disks
Invoke-TrueNASAPI -TN $tn -Method Get -Url "disk" #| Format-Table -AutoSize
# Get unused disks
Invoke-TrueNASAPI -TN $tn -Method Post -Url "disk/get_unused"
# Get information on all pools
Invoke-TrueNASAPI -TN $tn -Method Get -Url "pool"
Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/ntpserver" #| Format-Table -AutoSize
Invoke-TrueNASAPI -TN $tn -Method Get -Url "boot/get_disks"
}
Function SetDns {
param ([string] $tn)
$DNS1 = Get-Variable -Name "${TN}_DNS1" -ValueOnly
$DNS2 = Get-Variable -Name "${TN}_DNS2" -ValueOnly
$DNS3 = Get-Variable -Name "${TN}_DNS3" -ValueOnly
$GetNetworkConfig = Invoke-TrueNASAPI -TN $tn -Method Get -Url "network/configuration"
$CurrentDns1 = $GetNetworkConfig.nameserver1
$CurrentDns2 = $GetNetworkConfig.nameserver2
$CurrentDns3 = $GetNetworkConfig.nameserver3
Write-Output "Current DNS Settings:"
Write-Output "nameserver1 [$CurrentDns1]"
Write-Output "nameserver2 [$CurrentDns2]"
Write-Output "nameserver3 [$CurrentDns3]"
# Only update DNS if it is different from the desired state
if ($CurrentDns1 -ne $DNS1 -or $CurrentDns2 -ne $DNS2 -or $CurrentDns3 -ne $DNS3) {
# Define the DNS properties
$DnsProperties = @{
nameserver1 = $DNS1
nameserver2 = $DNS2
nameserver3 = $DNS3
}
$DnsPropertiesJson = $DnsProperties | ConvertTo-Json
$response = Invoke-TrueNASAPI -TN $tn -Method PUT -Url "network/configuration" -body $DnsPropertiesJson
# Check response
if ($response) {
$UpdatedDNS = Invoke-TrueNASAPI -TN $tn -Method Get -Url "network/configuration"
$UpdatedDns1 = $UpdatedDNS.nameserver1
$UpdatedDns2 = $UpdatedDNS.nameserver2
$UpdatedDns3 = $UpdatedDNS.nameserver3
Write-Output "DNS updated to:"
Write-Output "nameserver1 [$UpdatedDns1]"
Write-Output "nameserver2 [$UpdatedDns2]"
Write-Output "nameserver3 [$UpdatedDns3]"
} else {
Write-Output "Error updating DNS: $($response | ConvertTo-Json -Depth 100)"
}
} else {
Write-Output "DNS is already set to the desired values. No update needed."
}
}
Function SetHostName {
param ([string] $tn)
$NewHostname = Get-Variable -Name "${TN}_hostname" -ValueOnly
$CurrentHostname = Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/hostname"
# Only update hostname if it is different from the desired state
if ($CurrentHostname -ne $NewHostname) {
$NewHostnameData = '{ "hostname": ' + '"' + $NewHostname + '" }'
$response = Invoke-TrueNASAPI -TN $tn -Method PUT -Url "network/configuration" -body $NewHostnameData
# Check response
if ($response) {
$UpdatedHostname = Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/hostname"
Write-Output "Updated Hostname [$UpdatedHostname]"
} else {
Write-Output "Error updating hostname: $($response | ConvertTo-Json -Depth 100)"
}
} else {
Write-Output "Hostname is already set to [$NewHostname]. No update needed."
}
}
Function SetDomainName {
param ([string] $tn)
$DomainName = Get-Variable -Name "DomainName" -ValueOnly
# Get the current domain name
$GetNetworkConfig = Invoke-TrueNASAPI -TN $tn -Method Get -Url "network/configuration"
$CurrentDomainName = $GetNetworkConfig.domain
# Only update the domain name if it is different from the desired state
if ($CurrentDomainName -ne $DomainName) {
# Construct the request body
$DomainNameBody = @{
"domain" = $DomainName
}
$DomainNameJson = $DomainNameBody | ConvertTo-Json
# Call the TrueNAS API to set the domain name
$response = Invoke-TrueNASAPI -TN $tn -Method Put -Url "network/configuration" -Body $DomainNameJson
if ($response) {
$UpdatedNetworkConfig = Invoke-TrueNASAPI -TN $tn -Method Get -Url "network/configuration"
$UpdatedDomainName = $UpdatedNetworkConfig.domain
Write-Host "Domain name has been updated to [$UpdatedDomainName]"
} else {
Write-Host "Failed to set the domain name: $($response | ConvertTo-Json -Depth 100)"
}
} else {
Write-Output "Domain name is already set to [$DomainName]. No update needed."
}
}
Function SetNtpServers {
param ([string] $tn)
# Retrieve the desired NTP servers from variables
$NTP1 = Get-Variable -Name "${TN}_NTP1" -ValueOnly
$NTP2 = Get-Variable -Name "${TN}_NTP2" -ValueOnly
$NTP3 = Get-Variable -Name "${TN}_NTP3" -ValueOnly
# Retrieve the current NTP server configuration
$GetNtpConfig = Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/ntpserver"
$CurrentNtpServers = $GetNtpConfig | Select-Object -ExpandProperty address
Write-Output "Current NTP Servers:"
$CurrentNtpServers | ForEach-Object { Write-Output "NTP Server [$($_)]" }
# Only update NTP servers if they are different from the desired state
$desiredNtpServers = @($NTP1, $NTP2, $NTP3)
$serversToAdd = $desiredNtpServers | Where-Object { $_ -notin $CurrentNtpServers }
$serversToRemove = $CurrentNtpServers | Where-Object { $_ -notin $desiredNtpServers }
if ($serversToAdd.Count -eq 0 -and $serversToRemove.Count -eq 0) {
Write-Output "NTP servers are already set to the desired values. No update needed."
} else {
# Remove old NTP servers
foreach ($server in $serversToRemove) {
$ntpServerId = ($GetNtpConfig | Where-Object { $_.address -eq $server }).id
Invoke-TrueNASAPI -TN $tn -Method Delete -Url "system/ntpserver/$ntpServerId"
Write-Host "Removed NTP server: $server"
}
# Add new NTP servers
foreach ($server in $serversToAdd) {
$ntpServer = @{
address = $server
burst = $false
iburst = $true
prefer = $false
}
$ntpServerJson = $ntpServer | ConvertTo-Json
Invoke-TrueNASAPI -TN $tn -Method Post -Url "system/ntpserver" -Body $ntpServerJson
Write-Host "Added NTP server: $server"
}
Write-Host "NTP servers have been updated successfully."
}
}
Function CreateZ1Pool {
param ([string] $tn)
# Check if the pool already exists
$existingPools = Invoke-TrueNASAPI -TN $tn -Method Get -Url "pool"
$existingPool = $existingPools | Where-Object { $_.name -eq $PoolName }
if ($existingPool) {
Write-Output "Pool [$PoolName] already exists. No action needed."
return
}
$unusedDisks = Invoke-TrueNASAPI -TN $tn -Method Post -Url "disk/get_unused"
$bCreateZ1Pool = $false
# Check for unused disks
if ($unusedDisks.Count -eq 0) {
Write-Host "No unused disks found!"
return
}
Write-Host "[$($unusedDisks.Count)] unused disks found!"
$unusedDisks.devname | ForEach-Object { Write-Host "[$_]" }
$UnusedDiskDevs = $unusedDisks | Where-Object { $_.serial -ne $null -and $_.serial -ne "" } | Select-Object -ExpandProperty devname
if ($UnusedDiskDevs.Count -lt 3) {
Write-Host "Less than 3 disks with valid serial numbers found! Pool creation requires at least 3 disks."
return
}
Write-Host "[$($UnusedDiskDevs.Count)] disks with valid serial numbers found!"
$bCreateZ1Pool = $true
if ($bCreateZ1Pool) {
$zpoolConfig = @{
"name" = $PoolName
"encryption" = $false
"deduplication" = $null
"checksum" = $null
"topology" = @{
"data" = @(
@{
"disks" = $UnusedDiskDevs
"type" = $RaidType
}
)
}
"allow_duplicate_serials" = $false
}
$zpoolConfigJson = $zpoolConfig | ConvertTo-Json -Depth 100
# Create ZFS pool (RAID-Z1)
$createPoolResponseID = Invoke-TrueNASAPI -TN $tn -Method Post -Url "pool" -Body $zpoolConfigJson
$jobUrl = "core/get_jobs/?id=" + $createPoolResponseID
do {
$GetState = Invoke-TrueNASAPI -TN $tn -Method Get -Url $jobUrl
$GetState
if ($GetState.State -eq "RUNNING") {
Write-Output "Please wait..."
Start-Sleep -Seconds 10
}
} while ($GetState.State -eq "RUNNING")
}
}
Function CreateGroupAndUserForSmb {
param ([string] $tn)
$WindowsShareGroup = Get-Variable -Name "${TN}_WindowsShareGroup" -ValueOnly
# Check if the group already exists
$existingGroups = Invoke-TrueNASAPI -TN $tn -Method Get -Url "group"
$existingGroup = $existingGroups | Where-Object { $_.group -eq $WindowsShareGroup }
if ($existingGroup) {
Write-Output "Group [$WindowsShareGroup] already exists. No action needed."
$groupId = $existingGroup.id
} else {
# Define the group properties
$groupProperties = @{
name = $WindowsShareGroup
smb = $true
allow_duplicate_gid = $false
}
$groupPropertiesJson = $groupProperties | ConvertTo-Json
# Create the group
$createGroupResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "group" -body $groupPropertiesJson
$groupId = $createGroupResponse
# Debugging step: Output the entire group creation response
Write-Host "Group creation response: $groupId"
}
# Debugging step: Output the group ID
Write-Host "Group ID: $groupId"
# Check if the user already exists
$existingUsers = Invoke-TrueNASAPI -TN $tn -Method Get -Url "user"
$existingUser = $existingUsers | Where-Object { $_.username -eq $WindowsShareUser1Username }
if ($existingUser) {
Write-Output "User [$WindowsShareUser1Username] already exists. No action needed."
} else {
# Define the user properties
$userProperties = @{
username = $WindowsShareUser1Username
full_name = $WindowsShareUser1FullName
password = $WindowsShareUser1Password
smb = $true
group = $groupId
}
$userPropertiesJson = $userProperties | ConvertTo-Json
# Debugging step: Output the user creation JSON
Write-Host "User creation JSON: $userPropertiesJson"
# Create the user
$createUserResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "user" -body $userPropertiesJson
Write-Host "User created id [$createUserResponse]"
}
}
Function CreateDatasetForSmbShare {
param ([string] $tn)
$WindowsShareName = Get-Variable -Name "${TN}_WindowsShareName" -ValueOnly
# Define dataset parameters
$datasetName = $WindowsShareName
$SmbShareName = $datasetName
$datasetPath = "$poolName/$datasetName"
$datasetMntPath = "/mnt/$poolName/$datasetName"
# Check if the dataset already exists
$existingDatasets = Invoke-TrueNASAPI -TN $tn -Method Get -Url "pool/dataset"
$datasetExists = $existingDatasets | Where-Object { $_.name -eq $datasetPath }
if ($datasetExists) {
Write-Host "Dataset [$datasetName] already exists. No action needed."
} else {
# Create SMB dataset
$datasetBody = @{
"name" = $datasetPath
"type" = "FILESYSTEM"
"comments" = "Dataset for $datasetName"
"casesensitivity" = "INSENSITIVE"
"aclmode" = "RESTRICTED"
"share_type" = "SMB"
}
$datasetBodyJson = $datasetBody | ConvertTo-Json
$createDatasetResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "pool/dataset" -body $datasetBodyJson
# Check if dataset creation was successful
if ($createDatasetResponse.name -eq $datasetPath) {
Write-Host "Dataset [$datasetName] created successfully."
} else {
Write-Host "Failed to create dataset [$datasetName]."
}
}
}
Function CreateSmbShare {
param ([string] $tn)
$WindowsShareName = Get-Variable -Name "${TN}_WindowsShareName" -ValueOnly
$WindowsShareReadOnly = Get-Variable -Name "${TN}_WindowsShareReadOnly" -ValueOnly
# Define dataset parameters
$datasetName = $WindowsShareName
$SmbShareName = $datasetName
$PoolName = $PoolName # also defined elsewhere when creating dataset
$datasetPath = "$poolName/$datasetName"
$datasetMntPath = "/mnt/$poolName/$datasetName"
# Check if the SMB share already exists
$existingSmbShares = Invoke-TrueNASAPI -TN $tn -Method Get -Url "sharing/smb"
$smbShareExists = $existingSmbShares | Where-Object { $_.name -eq $SmbShareName }
if ($smbShareExists) {
Write-Host "SMB Share [$SmbShareName] already exists. No action needed."
} else {
# Define the SMB share properties
$smbShareProperties = @{
name = $SmbShareName
path = $datasetMntPath # Specify the path to the dataset
ro = $WindowsShareReadOnly # set read-only access
guestok = $false # Disable guest access
acl = $true # Enable support for storing the SMB Security Descriptor as a Filesystem ACL
streams = $true # Enable support for storing alternate datastreams as filesystem extended attributes
fsrvp = $true # Enable support for the filesystem remote VSS protocol
shadowcopy = $true # Enable support for the volume shadow copy service
audit = @{
enable = $true # Enable SMB share auditing
watch_list = @() # Specify a list of groups for which to generate audit messages (defaults to all groups)
ignore_list = @() # Specify a list of groups to ignore when auditing
}
}
$smbSharePropertiesJson = $smbShareProperties | ConvertTo-Json
# Create the SMB share
$createSmbShareResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "sharing/smb" -body $smbSharePropertiesJson
# Check if SMB share creation was successful
if ($createSmbShareResponse.name -eq $SmbShareName) {
Write-Host "SMB Share [$SmbShareName] created successfully."
} else {
Write-Host "Failed to create SMB Share [$SmbShareName]."
}
}
}
Function UpdateSmbNetbios {
param ([string] $tn)
$Hostname = Get-Variable -Name "${TN}_hostname" -ValueOnly
if ($Hostname.Length -gt 15) {
$Hostname = $Hostname.Substring(0, 15)
}
# Retrieve current SMB configuration
$currentSmbConfig = Invoke-TrueNASAPI -TN $tn -Method Get -Url "smb"
$currentNetbiosName = $currentSmbConfig.netbiosname
# Only update NetBIOS name if it is different from the desired state
if ($currentNetbiosName -ne $Hostname) {
# Define the SMB share properties
$smbNetbiosProperties = @{
netbiosname = $Hostname
}
$smbNetbiosPropertiesJson = $smbNetbiosProperties | ConvertTo-Json
# Update the SMB configuration
$updateSmbNetbiosResponse = Invoke-TrueNASAPI -TN $tn -Method Put -Url "smb" -body $smbNetbiosPropertiesJson
# Check response
if ($updateSmbNetbiosResponse) {
$updatedSmbConfig = Invoke-TrueNASAPI -TN $tn -Method Get -Url "smb"
$updatedNetbiosName = $updatedSmbConfig.netbiosname
Write-Output "NetBIOS name has been updated to [$updatedNetbiosName]"
} else {
Write-Output "Failed to update NetBIOS name: $($updateSmbNetbiosResponse | ConvertTo-Json -Depth 100)"
}
} else {
Write-Output "NetBIOS name is already set to [$Hostname]. No update needed."
}
}
Function EnabledSmbSnapshots-every5min-keep24hours {
param ([string] $tn)
$WindowsShareName = Get-Variable -Name "${TN}_WindowsShareName" -ValueOnly
# Define variables
$datasetName = $WindowsShareName
$datasetPath = "$poolName/$datasetName"
# Define the desired snapshot task payload
$snapshotTask = @{
naming_schema = "%Y_%m_%d_%H_%M_5Min_Snapshot_Task" # Adjusted naming schema
recursive = $false
lifetime_value = 24
lifetime_unit = "HOUR"
schedule = @{
minute = "0,5,10,15,20,25,30,35,40,45,50,55"
hour = "*"
dom = "*"
month = "*"
dow = "*"
}
enabled = $true
dataset = $datasetPath
}
$snapshotTaskPayload = $snapshotTask | ConvertTo-Json
# Get existing snapshot tasks
$existingSnapshotTasks = Invoke-TrueNASAPI -TN $tn -Method Get -Url "pool/snapshottask"
# Check if the desired snapshot task already exists
$taskExists = $false
$taskId = $null
foreach ($task in $existingSnapshotTasks) {
if ($task.dataset -eq $datasetPath -and $task.naming_schema -eq $snapshotTask.naming_schema) {
$taskExists = $true
$taskId = $task.id
# Check if the configuration is the same
if ($task.recursive -eq $snapshotTask.recursive -and
$task.lifetime_value -eq $snapshotTask.lifetime_value -and
$task.lifetime_unit -eq $snapshotTask.lifetime_unit -and
$task.schedule.minute -eq $snapshotTask.schedule.minute -and
$task.schedule.hour -eq $snapshotTask.schedule.hour -and
$task.schedule.dom -eq $snapshotTask.schedule.dom -and
$task.schedule.month -eq $snapshotTask.schedule.month -and
$task.schedule.dow -eq $snapshotTask.schedule.dow -and
$task.enabled -eq $snapshotTask.enabled) {
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] and the desired configuration already exists. No action needed."
return
} else {
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] exists but with a different configuration. Updating..."
# Update the existing snapshot task
$updateSnapshotTaskPayload = @{
naming_schema = $snapshotTask.naming_schema
recursive = $snapshotTask.recursive
lifetime_value = $snapshotTask.lifetime_value
lifetime_unit = $snapshotTask.lifetime_unit
schedule = $snapshotTask.schedule
enabled = $snapshotTask.enabled
dataset = $snapshotTask.dataset
} | ConvertTo-Json
$updateUrl = "pool/snapshottask/id/$taskId"
Write-Output "Updating snapshot task at URL: https://$($tn)/api/v2.0/$updateUrl"
$updateResponse = Invoke-TrueNASAPI -TN $tn -Method Put -Url $updateUrl -body $updateSnapshotTaskPayload
if ($updateResponse) {
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] updated successfully."
} else {
Write-Host "Failed to update the snapshot task."
}
return
}
}
}
# Create the periodic snapshot task if it does not exist
if (-not $taskExists) {
$createResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "pool/snapshottask" -body $snapshotTaskPayload
if ($createResponse) {
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] created successfully."
} else {
Write-Host "Failed to create the snapshot task."
}
}
}
Function EnabledSmbSnapshots-every8hours-keep7days {
param ([string] $tn)
$WindowsShareName = Get-Variable -Name "${TN}_WindowsShareName" -ValueOnly
# Define variables
$datasetName = $WindowsShareName
$datasetPath = "$poolName/$datasetName"
# Define the desired snapshot task payload
$snapshotTask = @{
naming_schema = "%Y_%m_%d_%H_%M_8Hour_Snapshot_Task" # Adjusted naming schema
recursive = $false
lifetime_value = 7
lifetime_unit = "DAY"
schedule = @{
minute = "0"
hour = "*/8"
dom = "*"
month = "*"
dow = "*"
}
enabled = $true
dataset = $datasetPath
}
$snapshotTaskPayload = $snapshotTask | ConvertTo-Json
# Get existing snapshot tasks
$existingSnapshotTasks = Invoke-TrueNASAPI -TN $tn -Method Get -Url "pool/snapshottask"
# Check if the desired snapshot task already exists
$taskExists = $false
foreach ($task in $existingSnapshotTasks) {
if ($task.dataset -eq $datasetPath -and $task.naming_schema -eq $snapshotTask.naming_schema) {
$taskExists = $true
# Check if the configuration is the same
if ($task.recursive -eq $snapshotTask.recursive -and
$task.lifetime_value -eq $snapshotTask.lifetime_value -and
$task.lifetime_unit -eq $snapshotTask.lifetime_unit -and
$task.schedule.minute -eq $snapshotTask.schedule.minute -and
$task.schedule.hour -eq $snapshotTask.schedule.hour -and
$task.schedule.dom -eq $snapshotTask.schedule.dom -and
$task.schedule.month -eq $snapshotTask.schedule.month -and
$task.schedule.dow -eq $snapshotTask.schedule.dow -and
$task.enabled -eq $snapshotTask.enabled) {
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] and the desired configuration already exists. No action needed."
return
} else {
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] exists but with a different configuration. Updating..."
# Update the existing snapshot task
$updateSnapshotTaskPayload = @{
naming_schema = $snapshotTask.naming_schema
recursive = $snapshotTask.recursive
lifetime_value = $snapshotTask.lifetime_value
lifetime_unit = $snapshotTask.lifetime_unit
schedule = $snapshotTask.schedule
enabled = $snapshotTask.enabled
dataset = $snapshotTask.dataset
} | ConvertTo-Json
Invoke-TrueNASAPI -TN $tn -Method Put -Url "pool/snapshottask/$($task.id)" -body $updateSnapshotTaskPayload
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] updated successfully."
return
}
}
}
# Create the periodic snapshot task if it does not exist
if (-not $taskExists) {
Invoke-TrueNASAPI -TN $tn -Method Post -Url "pool/snapshottask" -body $snapshotTaskPayload
Write-Host "Snapshot task for dataset [$datasetPath] with the naming schema [$($snapshotTask.naming_schema)] created successfully."
}
}
Function ShowSnapshotTasks {
param ([string] $tn)
$ShowSnapshotTasks = Invoke-TrueNASAPI -TN $tn -Method Get -Url "pool/snapshottask"
$ShowSnapshotTasks
}
Function SetSmbAcl {
param ([string] $tn)
$WindowsShareName = Get-Variable -Name "${TN}_WindowsShareName" -ValueOnly
# Define dataset parameters
$datasetName = $WindowsShareName
$SmbShareName = $datasetName
$datasetPath = "$poolName/$datasetName"
$datasetMntPath = "/mnt/$poolName/$datasetName"
# Show current ACL
$AclProperties = @{
path = $datasetMntPath
simplified = $true
resolve_ids = $false
}
$AclPropertiesJson = $AclProperties | ConvertTo-Json -Depth 100
$AclPropertiesResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "filesystem/getacl" -body $AclPropertiesJson
$currentAcl = $AclPropertiesResponse.acl
Write-Output "Current ACL:"
$currentAcl | Format-Table -AutoSize
# Define the desired ACL payload
$desiredAcl = @(
@{
tag="owner@"
id=-1
perms=@{BASIC="FULL_CONTROL"}
flags=@{BASIC="INHERIT"}
type="ALLOW"
},
@{
tag="group@"
id=-1
perms=@{BASIC="MODIFY"}
flags=@{BASIC="INHERIT"}
type="ALLOW"
},
@{
tag="GROUP"
id=3000
perms=@{BASIC="FULL_CONTROL"}
flags=@{BASIC="INHERIT"}
type="ALLOW"
}
)
# Compare current ACL with the desired ACL
$aclMatches = $true
if ($currentAcl.Count -ne $desiredAcl.Count) {
$aclMatches = $false
} else {
for ($i = 0; $i -lt $currentAcl.Count; $i++) {
if ($currentAcl[$i].tag -ne $desiredAcl[$i].tag -or
$currentAcl[$i].id -ne $desiredAcl[$i].id -or
$currentAcl[$i].perms.BASIC -ne $desiredAcl[$i].perms.BASIC -or
$currentAcl[$i].flags.BASIC -ne $desiredAcl[$i].flags.BASIC -or
$currentAcl[$i].type -ne $desiredAcl[$i].type) {
$aclMatches = $false
break
}
}
}
if ($aclMatches) {
Write-Output "ACL for dataset [$datasetPath] is already set to the desired configuration. No action needed."
} else {
Write-Output "ACL for dataset [$datasetPath] is different from the desired configuration. Updating..."
$AclPayload = @{
dacl = $desiredAcl
uid = 0
gid = 0
path = $datasetMntPath
nfs41_flags = @{
protected = $false
defaulted = $false
autoinherit = $false
}
acltype = "NFS4"
}
$AclPayloadJson = $AclPayload | ConvertTo-Json -Depth 100
$AclSetResponseID = Invoke-TrueNASAPI -TN $tn -Method Post -Url "filesystem/setacl" -body $AclPayloadJson
$jobUrl = "core/get_jobs/?id=" + $AclSetResponseID
do {
$GetState = Invoke-TrueNASAPI -TN $tn -Method Get -Url $jobUrl
$GetState
if ($GetState.State -eq "RUNNING") {
Write-Output "please wait"
Start-Sleep -Seconds 10
}
} while ($GetState.State -eq "RUNNING")
Write-Output "ACL for dataset [$datasetPath] updated successfully."
}
}
Function SetupSShConnection {
param ([string] $tn)
$ReplUser = Get-Variable -Name "${TN}_ReplicationAccount" -ValueOnly
$ReplPassword = Get-Variable -Name "${TN}_ReplicationPassword" -ValueOnly
# Define ssh setup properties
$sshSetupProperties = @{
connection_name = "test2"
setup_type = "SEMI-AUTOMATIC"
semi_automatic_setup = @{
url = "http://10.23.252.38"
verify_ssl = $false
admin_username = "admin"
password = "password"
username = "root"
connect_timeout = 10
sudo = $false
}
private_key = @{
name = "test2_private_key" # Provide a name for the private key
}
}
$sshSetupPropertiesJson = $sshSetupProperties | ConvertTo-Json
# Check if the SSH connection already exists
$existingConnections = Invoke-TrueNASAPI -TN $tn -Method Get -Url "keychaincredential"
$existingConnection = $existingConnections | Where-Object { $_.name -eq $sshSetupProperties.connection_name }
$existingPrivateKey = $existingConnections | Where-Object { $_.name -eq $sshSetupProperties.private_key.name }
if ($existingConnection) {
Write-Host "SSH connection [$($sshSetupProperties.connection_name)] already exists. Checking configuration..."
# Check if the existing connection matches the desired configuration
$matches = $true
if ($existingConnection.setup_type -ne $sshSetupProperties.setup_type) { $matches = $false }
if ($existingConnection.semi_automatic_setup.url -ne $sshSetupProperties.semi_automatic_setup.url) { $matches = $false }
if ($existingConnection.semi_automatic_setup.admin_username -ne $sshSetupProperties.semi_automatic_setup.admin_username) { $matches = $false }
if ($existingConnection.semi_automatic_setup.username -ne $sshSetupProperties.semi_automatic_setup.username) { $matches = $false }
if ($matches) {
Write-Host "SSH connection [$($sshSetupProperties.connection_name)] already exists and matches the desired configuration. No action needed."
return
} else {
Write-Host "SSH connection [$($sshSetupProperties.connection_name)] exists but with different configuration. Attempting to update..."
# Optionally, you can delete the existing connection if it doesn't match
# Invoke-TrueNASAPI -TN $tn -Method Delete -Url "keychaincredential/$($existingConnection.id)"
}
}
if ($existingPrivateKey) {
Write-Host "Private key [$($sshSetupProperties.private_key.name)] already exists. Using existing key..."
# If the private key already exists, use the existing key id
$sshSetupProperties.private_key.id = $existingPrivateKey.id
$sshSetupPropertiesJson = $sshSetupProperties | ConvertTo-Json
}
try {
# Create or update the SSH connection
$sshSetupResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "keychaincredential/setup_ssh_connection" -body $sshSetupPropertiesJson
Write-Host "SSH connection setup response: $($sshSetupResponse | ConvertTo-Json -Depth 10)"
} catch {
Write-Host "Error setting up SSH connection: $($_.Exception.Message)"
if ($_.Exception.Response -and $($_.Exception.Response.StatusCode) -eq 422) {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$errorResponse = $reader.ReadToEnd() | ConvertFrom-Json
$reader.Close()
if ($errorResponse.'setup_ssh_connection.private_key.name') {
Write-Host "Error: Private key name is already in use by another SSH Key pair."
# Additional logic to handle the error (e.g., choosing a different name or using the existing key)
}
if ($errorResponse.'setup_ssh_connection.connection_name') {
Write-Host "Error: Connection name is already in use by another Keychain Credential."
# Additional logic to handle the error (e.g., choosing a different name or using the existing connection)
}
}
}
}
Function ListAllKeychainCredentials {
param ([string] $tn)
$credentials = Invoke-TrueNASAPI -TN $tn -Method Get -Url "keychaincredential"
return $credentials
}
Function CreateReplicationTasksForSnapshots {
param (
[string] $sourceTN,
[string] $targetTN
)
# Get the list of snapshot tasks from the source TrueNAS system
$snapshotTasks = Invoke-TrueNASAPI -TN $sourceTN -Method Get -Url "pool/snapshottask"
# Get the SSH credential ID
$sshCredentials = Invoke-TrueNASAPI -TN $sourceTN -Method Get -Url "keychaincredential"
$sshCredential = $sshCredentials | Where-Object { $_.type -eq "SSH_CREDENTIALS" }
if (-not $sshCredential) {
Write-Host "No SSH credential found. Please ensure an SSH credential exists."
return
}
$sshCredentialId = $sshCredential.id
# Get existing replication tasks
$existingReplicationTasks = Invoke-TrueNASAPI -TN $sourceTN -Method Get -Url "replication"
foreach ($snapshotTask in $snapshotTasks) {
$snapshotTaskId = $snapshotTask.id
$snapshotTaskDataset = $snapshotTask.dataset
# Define the target dataset for replication
$targetDataset = $snapshotTaskDataset -replace "^([^/]+)/", "`$1/$ReplicationPrependText"
# Define the desired replication task payload
$desiredReplicationTask = @{
name = "Replication_${snapshotTaskId}"
auto = $true
retention_policy = "SOURCE"
allow_from_scratch = $true
periodic_snapshot_tasks = @($snapshotTaskId)
target_dataset = $targetDataset
source_datasets = @($snapshotTaskDataset)
recursive = $false
direction = "PUSH"
transport = "SSH"
enabled = $true
readonly = "SET"
compressed = $true
ssh_credentials = $sshCredentialId
}
# Convert to JSON for comparison
$desiredReplicationTaskJson = $desiredReplicationTask | ConvertTo-Json -Depth 10
# Check if the replication task already exists
$existingTask = $existingReplicationTasks | Where-Object { $_.name -eq "Replication_${snapshotTaskId}" }
if ($existingTask) {
# Extract the relevant properties for comparison
$existingTaskConfig = @{
auto = $existingTask.auto
ssh_credentials = $existingTask.ssh_credentials.id
periodic_snapshot_tasks = $existingTask.periodic_snapshot_tasks.id
source_datasets = $existingTask.source_datasets
recursive = $existingTask.recursive
readonly = $existingTask.readonly
name = $existingTask.name
direction = $existingTask.direction
retention_policy = $existingTask.retention_policy
allow_from_scratch = $existingTask.allow_from_scratch
transport = $existingTask.transport
target_dataset = $existingTask.target_dataset
enabled = $existingTask.enabled
compressed = $existingTask.compressed
}
# Compare existing task configuration with the desired configuration
$updateNeeded = $false
Write-Host "Comparing existing task with desired task:"
foreach ($key in $desiredReplicationTask.Keys) {
if ($desiredReplicationTask[$key] -ne $existingTaskConfig[$key]) {
Write-Host "Difference found in key: $key"
Write-Host "Existing value: $($existingTaskConfig[$key])"
Write-Host "Desired value: $($desiredReplicationTask[$key])"
$updateNeeded = $true
}
}
if ($updateNeeded) {
# Update the existing replication task only if configurations do not match
$replicationTaskId = $existingTask.id
$updateResponse = Invoke-TrueNASAPI -TN $sourceTN -Method Put -Url "replication/id/$replicationTaskId" -Body $desiredReplicationTaskJson
if ($updateResponse) {
Write-Host "Replication task for snapshot task [$snapshotTaskId] updated successfully."
} else {
Write-Host "Failed to update replication task for snapshot task [$snapshotTaskId]."
}
} else {
Write-Host "Replication task for snapshot task [$snapshotTaskId] is already up-to-date. No changes made."
}
} else {
# Create a new replication task
$createResponse = Invoke-TrueNASAPI -TN $sourceTN -Method Post -Url "replication" -Body $desiredReplicationTaskJson
if ($createResponse) {
Write-Host "Replication task for snapshot task [$snapshotTaskId] created successfully."
} else {
Write-Host "Failed to create replication task for snapshot task [$snapshotTaskId]."
}
}
}
}
Function ShowReplicationTask{
param ([string] $tn)
$GetReplication = Invoke-TrueNASAPI -TN $tn -Method Get -Url "replication"
$GetReplication
}
Function SetSnmpService {
param ([string] $tn)
# Desired SNMP configuration
$desiredCommunity = $Script:SnmpRo
$desiredEnable = $Script:SnmpEnable
# Get current SNMP configuration
$snmpConfig = Invoke-TrueNASAPI -TN $tn -Method Get -Url "snmp"
$currentCommunity = $snmpConfig.community
# Check if SNMP community needs to be updated
if ($currentCommunity -ne $desiredCommunity) {
# Update SNMP community
$snmpPayload = @{
community = $desiredCommunity
}
$snmpPayloadJson = $snmpPayload | ConvertTo-Json -Depth 10
$updateSnmpResponse = Invoke-TrueNASAPI -TN $tn -Method Put -Url "snmp" -Body $snmpPayloadJson
if ($updateSnmpResponse -ne $null) {
Write-Host "SNMP community updated successfully."
} else {
Write-Host "Failed to update SNMP community."
}
} else {
Write-Host "SNMP community is already up-to-date. No changes made."
}
# Ensure SNMP service is enabled and running
$services = Invoke-TrueNASAPI -TN $tn -Method Get -Url "service"
$snmpService = $services | Where-Object { $_.service -eq "snmp" }
if ($snmpService.enable -ne $desiredEnable) {
# Enable or disable the SNMP service
$enableSnmpPayload = @{
enable = $desiredEnable
}
$enableSnmpPayloadJson = $enableSnmpPayload | ConvertTo-Json -Depth 10
$enableSnmpResponse = Invoke-TrueNASAPI -TN $tn -Method Put -Url "service/id/$($snmpService.id)" -Body $enableSnmpPayloadJson
if ($enableSnmpResponse -ne $null) {
Write-Host "SNMP service state updated successfully."
} else {
Write-Host "Failed to update SNMP service state."
}
} else {
Write-Host "SNMP service state is already set as desired."
}
if ($snmpService.state -eq "RUNNING") {
Write-Host "SNMP service is already running. No action needed."
} else {
# Start the SNMP service
$startServicePayload = @{
service = "snmp"
}
$startServicePayloadJson = $startServicePayload | ConvertTo-Json -Depth 10
try {
$startServiceResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "service/start" -Body $startServicePayloadJson
# Check the response
if ($startServiceResponse -eq $true) {
Write-Host "SNMP service started successfully."
} else {
Write-Host "Failed to start SNMP service."
}
} catch {
Write-Host "Failed to start SNMP service. Error: $_"
}
}
}
Function EnabledHttpRedirect {
param ([string] $tn)
# Retrieve current HTTPS settings
$httpResponse = Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/general"
$ui_port = $httpResponse.ui_port
$ui_httpsport = $httpResponse.ui_httpsport
$ui_httpsredirect = $httpResponse.ui_httpsredirect
$ui_httpsprotocols = $httpResponse.ui_httpsprotocols
Write-host "Current HTTP/HTTPS settings"
$ui_port
$ui_httpsport
$ui_httpsredirect
$ui_httpsprotocols
# Check if HTTPS is enabled
if (-not $ui_httpsredirect) {
# Configure HTTPS settings (you'll need to replace placeholders with actual certificate paths etc.)
$EnableRedirects = @{ "ui_httpsredirect" = $true }
$EnableRedirectsJson = $EnableRedirects | ConvertTo-Json
$configureHttpsResponse = Invoke-TrueNASAPI -TN $tn -Method Put -Url "system/general" -body $EnableRedirectsJson
# Check if configuration was successful
if ($configureHttpsResponse.ui_httpsredirect -eq $true) {
Write-Host "HTTPS configured successfully."
} else {
Write-Host "Failed to configure HTTPS."
}
}
}
Function DisableHttpRedirect {
param ([string] $tn)
# Retrieve current HTTPS settings
$httpResponse = Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/general"
$ui_httpsredirect = $httpResponse.ui_httpsredirect
if ($ui_httpsredirect) {
Write-Host "HTTP to HTTPS redirect is currently enabled. Disabling it now..."
# Disable HTTPS redirect
$disableRedirects = @{ "ui_httpsredirect" = $false }
$disableRedirectsJson = $disableRedirects | ConvertTo-Json
$disableRedirectResponse = Invoke-TrueNASAPI -TN $tn -Method Put -Url "system/general" -Body $disableRedirectsJson
# Check if the response indicates success
if ($disableRedirectResponse.ui_httpsredirect -eq $false) {
Write-Host "HTTP to HTTPS redirect has been disabled successfully."
} else {
Write-Host "Failed to disable HTTP to HTTPS redirect. Response:"
Write-Host ($disableRedirectResponse | ConvertTo-Json -Depth 100)
}
} else {
Write-Host "HTTP to HTTPS redirect is already disabled. No action needed."
}
}
Function TestHttpRedirect {
param ([string] $tn)
# Retrieve current HTTPS settings
$httpResponse = Invoke-TrueNASAPI -TN $tn -Method Get -Url "system/general"
# Check if HTTPS redirect is enabled
$ui_httpsredirect = $httpResponse.ui_httpsredirect
if ($ui_httpsredirect) {
Write-Host "HTTP to HTTPS redirect is enabled."
} else {
Write-Host "HTTP to HTTPS redirect is not enabled."
}
}
Function SetSmbServiceAutostart {
param ([string] $tn)
# Retrieve the current status of the SMB service
$services = Invoke-TrueNASAPI -TN $tn -Method Get -Url "service"
$smbService = $services | Where-Object { $_.service -eq 'cifs' }
$smbId = $smbService.id
$currentAutostart = $smbService.enable
# Check if the SMB service is already set to autostart
if ($currentAutostart -eq $true) {
Write-Host "SMB service is already set to autostart. No action needed."
} else {
# Set SMB service to start on boot
$smbServiceAutostart = @{
enable = $true
}
$smbServiceAutostartJson = $smbServiceAutostart | ConvertTo-Json
$updateResponse = Invoke-TrueNASAPI -TN $tn -Method Put -Url "service/id/$smbId" -Body $smbServiceAutostartJson
# Check the response
if ($updateResponse -ne $null) {
Write-Host "SMB service set to autostart successfully. Response:"
Write-Host ($updateResponse | ConvertTo-Json -Depth 100)
} else {
Write-Host "Failed to set SMB service to autostart. Response:"
Write-Host ($updateResponse | ConvertTo-Json -Depth 100)
}
}
# Start the SMB service if it's not already running
if ($smbService.state -ne "RUNNING") {
$startServicePayload = @{
service = "cifs"
}
$startServicePayloadJson = $startServicePayload | ConvertTo-Json -Depth 10
try {
$startServiceResponse = Invoke-TrueNASAPI -TN $tn -Method Post -Url "service/start" -Body $startServicePayloadJson
# Check the response
if ($startServiceResponse -eq $true) {
Write-Host "SMB service started successfully."
} else {
Write-Host "Failed to start SMB service."
}
} catch {
Write-Host "Failed to start SMB service. Error: $_"
}
} else {
Write-Host "SMB service is already running. No action needed."
}
}