Gör skillnad – Med NetClean och VMware

Barnporr. Bara ett ord på skärmen när du läser det men innebörden av ordet är avgrundsdjup. Blir du arg när du tänker på det? Blir du illa till mods? Upprörd? Känner du något överhuvudtaget så vill du förmodligen hjälpa till att sätta stopp för det på alla sätt du kan. Det är långt vanligare än man kan tro att vuxna män – för det är onekligen män som är överrepresenterade här – innehar barnporr.

1 av 500 individer har tillgång till och konsumerar barnporr via sin arbetsdator.

Som företag – som ledare – som anställd – som människa – har vi ett ansvar att försöka stoppa det!

Vi på Arrow ECS har många leverantörer i vår portfölj, de flest är viktiga. En del till och med företagskritiska. Jag har tillexempel haft jobb i snart 20 år eftersom jag för länge sedan insåg potentialen som fanns i det där med virtualiering. Så för mig har VMware som leverantör varit viktig personligen, jag har kunnat livnära mig på den kunskap om de tekniker och funktioner som VMware genom åren släppt ut på marknaden. Jag kommer oerhört väl ihåg när jag upplevde vMotion för första gången – och imponeras fortfarande idag av hur otroligt det egentligen är att flytta en arbetslast från en fysisk server till en annan. Jag förstår att VMware har hjälpt till att transformera en hel bransch under 20 års tid med att först virtualisera servrar, sedan nätverk och dessutom storage – och resan är långt ifrån slut!

Men jag vill också tro att vi som människor, som råkar arbeta inom IT branschen, kan hjälpa till att göra världen lite bättre än den var igår. ”A force for good”. Det är därför jag som anställd är väldigt stolt att Arrow har tagit in en ny leverantör i vår portfölj. Det låter affärsmässigt, nya leverantörer får vi in hela tiden. Men hur ofta får vi in en leverantör som har en potential att hjälpa barn i utsatta positioner?  Att påverka vår omvärld långt utanför IT-branschen? NetClean, som jag pratar om här, är ett svenskt företag vars vision är att vara en given del i kampen mot sexuella övergrepp mot barn. Företaget startade 2003 och har sitt huvudsäte i Göteborg.

När man går in på NetCleans hemsida möts man av budskapet ”Protect what matters!” – Tre små ord som i sammanhanget får så oerhört stor betydelse. Även om det varit utbrett tidigare så har barnporr och övergrepp mot barn ökat i en skrämmande takt under pandemin, därför blir jag så glad när man kan kombinera nytt och gammalt på ett sätt som faktiskt gör skillnad. NetClean har nämligen samarbete med VMware där NetClean kan komplettera och integrera i två viktiga VMware-område: Carbon Black och Workspace ONE.

Med integreringen i dessa två område sitter NetClean verkligen i bästa position för att upptäcka och rapportera oönskade aktiviteter. NetClean har två produkter, en som skyddar datorer och en som skyddar mobiltelefoner. Infrastrukturen för att hantera NetClean är väldigt enkel att sätta upp och licensiering är enkel att förstå – per device.

Med NetClean och VMware kan vi alltså göra en konkret skillnad – här och nu!

Kontakta Arrow ECS eller NetClean idag för att komma vidare

  • VMware Carbon Black Cloud är en SaaS-lösning (Software as a Service) som omfattar nästa generations anti-virus (NGAV), endpoint detection and response (EDR), avancerad hothantering och sårbarhetshantering i en enda konsol med hjälp av en enda sensor
  • VMware Workspace ONE är en företagsplattform som tillhandahåller moduler som stöder identitetshantering, programpaketering och distribution samt hantering av mobila enheter.

VMworld 2021

Nya Cross-Cloud tjänster
Det var mycket nyheter runt hantering av multi-cloud miljöer, allt från managering och säkerhet till kostnadskontroll.
Men en av de största lanseringarna på VMworld 2021 var VMwares Cross-Cloud Services. Cross-Cloud Services är en samling integrerade tjänster som gör det möjligt för kunder att bygga, köra och säkra upp applikationer oavsett vilket moln de körs i.
Det finns fem grundläggande byggblock i Cross-Cloud Services:

  • Bygga och rulla ut cloud native applications
  • Cloud infrastruktur för att hantera och köra enterprise apps
  • Cloud management mellan olika moln
  • Säkerhet och nätverk
  • Digital Workspace för hantering av användare som är utspridda

Man lyfte också på vad som är på gång i form av Project Arctic som är en plattform för hantering av vSphere fast i molnet. Man integrerar koppling till molnet direkt i vSphere vilket innebär att vSphere blir “Cloud-aware” och hybrid cloud blir den nya operating model som används.

Mycket Tanzu
VMware släppte en gratisversion av Tanzu, VMware Tanzu Community Edition, som låter kunder testa och lära sig om applikationer i containers. Tanzu Community edition kan enkelt installeras på en laptop på några minuter. Kunder kan sen snabbt komma igång med sitt kubernetescluster.


Man annonserade även Tanzu Service Mesh som för samman hur man kopplar samman och hanterar säkerhet och monitorering över flera molnmiljöer.

VMware Tanzu Kubernetes Grid supporterar nu NVIDIA GPUs i Amazon Web Services och Azure

VMware Tanzu Mission Control Starter – Tanzu Mission Control släpptes i en gratis instegsvariant

Och dessutom släpptes vSphere 7.0 update 3 till allmänheten samt VMware Cloud Director 10.3 (som släpptes lite tidigare än VMworld)

How To: Install Cloudian with object lock for Veeam Backup & Replication 10 = Ransomwareprotection

In this blog post I’ll share how to setup Cloudian HyperStore 7.2.1, create an immutable bucket and how to make use of it in Veeam Backup & Replication v10 for testing purposes and getting your hands dirty with object lock which in essence will provide ransomware protection but first let me talk a little bit about why this is a big deal.

One of the most interesting and useful features in Veeam Backup & Replication version 10 is the “replacement for tapes”-feature called Immutability. Why does it replace tape I hear you ask. A few different reasons but the biggest to me is that you can protect your data from being tampered with just as with tape but unlike tape your data is still online and accesible. It’s built on an AWS S3 feature called Object lock, eventhough it’s originally from AWS that doesn’t mean that it’s only available for AWS users. There’s actually a growing list of object storage solutions and vendors implementing the latest AWS S3 API, both as cloud based solutions but also for on-premises solutions using either a hardware- or a software approach. Today the object lock functionality is supported by AWS S3 of course but also Zadara VPSA Object Storage (v 20.01 or later), Ceph (v14.2.6 or later) and Cloudian (v 7.2 or later). You can find the ever growing list of compatible object storage solutions that works with Veeam on this unofficial list which includes both object storage solutions with and without object lock functionality.

So let’s get back to basics, what exactly does the object lock feature do? Well, the short answer is that it write protects the data you save to on object storage solution for a period of time which you can define, making the data accessible to read (meaning online) but it cannot be changed or deleted untill that time has passed (so basically the equivalent of an offline tape but instantly accessible to recover from). “WORM” escentially, Write Once Read Many. Your data is still online and ready to be used if you need it but if your hit by some ransomware or malicious admin/hacker the data cannot be changed or deleted.

Want to kick the tires? Give it a spin? What you need: Veeam Backup & Replication v10, An Object Based storage solution, in this post I’ll be using Cloudian HyperStore, and an lab environment to deploy it all on. You will also need the AWS CLI when creating the S3 bucket in the Cloudian environment.

Download the AWS CLI, Cloudian HyperStore OVA and Veeam Backup & Replication from the links above. Install Veeam Backup & Replication on a VM.

Installing Cloudian HyperStore

I’m going to use a few new hostnames in my lab evenrionment, so first thing is to add those to my DNS server (I’m using a zone called vcsp.local where I’ll add the records):

  • cloudian01 / 192.168.50.231
  • cloudian02 / 192.168.50.232
  • cloudian03 / 192.168.50.233
  • cmc / 192.168.50.231, 192.168.50.232, 192.168.50.233
  • iam / 192.168.50.231, 192.168.50.232, 192.168.50.233
  • s3-nordics / 192.168.50.231, 192.168.50.232, 192.168.50.233
  • s3-admin / 192.168.50.231, 192.168.50.232, 192.168.50.233
  • s3-website-nordics / 192.168.50.231, 192.168.50.232, 192.168.50.233
  • sqs / 192.168.50.231, 192.168.50.232, 192.168.50.233

By adding a hostname with multiple IP address you will get a basic “load-balancer” distributing connections between the different nodes. It’s not a real load-balancer but the DNS server will resolve a hostname to a new IP address for every request it gets, this is called DNS Round-Robin. If you don’t have a DNS server you can install a lighweight DNS server as part of the Cloudian deployment called dnsmasq, when you get to the part where you install HyperStore (the step below that says “. /cloudianInstall.sh force“), replace it with the command “. /cloudInstall.sh dnsmasq force” instead.

Configure the three nodes:

  • Use Deploy OVF template in vSphere to install the Cloudian HyperStore OVA. Import the Cloudian HyperStore OVA 3 times using the names Cloudian01, Cloudian02 and Cloud03.
  • Change resource of the VMs to 8 vCPU and 16 GB RAM (which is the minimum requirement but in this limited test environment it works with fewer resources, I’ve tested with 2 vCPU and 8 GB RAM and it seems to work ok)
  • Power on VMs
  • Logon as root / password using the console
    cd CloudianTools
  • Run the following command and follow the steps
    ./system_setup.sh
  • 1) Configure Networking
  • 1) Ens160
    • Change IP address to static IP address
    • Set IP address, subnet mask, default gateway and DNS
    • Do you wish to save these settings? Yes
    • Will <IP address> be the address you use for hyperstore-ova in you survey file? Yes
    • Would you like to restart this interface to activate this new configuration? Yes
  • P) Return to the Previous Menu
  • D) Change Domain name
    • Do you want to change your domain name? Yes
    • New Domain Name: vcsp.local
  • H) Change Hostname
    • Do you want to change your hostname? Yes
    • New Hostname: cloudian01
      (cloudian02 and cloudian03 for subsequent nodes)
  • N) Restart Networking
    • Are you sure? Yes
  • P) Return to the Previous Menu
  • 2) Change Timezone
    • 8) Europe
    • 45) Sweden
    • Would you like to save this timezone setting? Yes
  • 5) Change root Password
    • 1) Change root Password
      • New Password: <new root password>
      • Retype New Password: <new root password>
    • P) Return to the Previous Menu
  • D) Download HyperStore Files (this step is only needed on the first node you install, i.e. cloudian01)
    • Select an option to download
      (if you only want to test object storage choose 1 but if you want to test object lock/immutability feature you need to choose 2)
      • 1) Download HyperStore GA files (HyperStore 7.1.7
      • 2) Download HyperStore EA files (HyperStore 7.2.1, required for Object Lock testing which is a licensed feature and not part of the trial license)
  • P) Return to the Previous Menu
  • X) Exit
  • Continue to cloudian02 and do the same steps above and then cloudian03

Install Cloudian HyperStore On Master (cloudian01 only):

  • On you PC/Mac using for instance WinSCP or CyberDuck, transfer your license file cloudian_<numbers>.lic to cloudian01 (there’s a trial license included in the download from the previous step that could be used but it doesn’t include the object lock functionality, you need to contact Cloudian to get a license to unlock that feature.
    • If needed, transfer the license file to /root/CloudianPackages/
      (or use the one already present in that folder, but again: it doesn’t provide Object Lock functionality)
  • Logon to VM using root / <new root password>
  • cd /root/CloudianPackages
  • ./CloudianHyperStore-7.2.1.bin cloudian_<numbers>.lic
  • cd /opt/cloudian-staging/7.2.1
  • ./system_setup.sh
    • 4) Setup Survey.csv File
      • Would you like to create a survey file now? Yes
      • Would you like to add entries now? Yes
      • Region Name: nordics
      • Hostname: cloudian01
      • IP Address: 192.168.50.231
      • Data Center Name: DC1
      • Rack name (all nodes in a DC must use same rack name): rac1
      • Internal Interface (optional): <skip this option by pressing enter>
      • Would you like to add another entry? Yes/No (you can have a 1 node test bed if you like or add 2 additional nodes if you’d like to test object lock)
  • P) Return to Previous Menu
    • S) Script Settings
      • 10) Generate SSH Key File
        • Install public key on cluster nodes? Yes
        • Enter password for each node
  • P) Return to the Previous Menu
    • 6) Install & Configure Prerequisites
      • 1) Install & Configure Prerequisites
        • Would you like to perform this on all nodes listed in you survey file? Yes
        • P) Return to the Previous Menu
      • R) Run Pre-installation Checks
        • 1) Quite mode: (show only warning or failed tests)
        • R) Run Pre-Install Checks
          • You will most likely get warnings that you running a virtualized environment, perhaps not enough nodes in the cluster and not enough resources allocated to the VM. If other issues show up as failed they need to be addressed before proceeding.
  • P) Return to the Previous Menu
    • W) Write sysctl Configuration
    • X) Exit
      • A reboot is required to apply some of the changes. Reboot cloudian01 now? Yes
  • Wait for cloudian01 to reboot
  • Logon as root / <new root password> using console or ssh
  • cd /opt/cloudian-staging/7.2.1/
  • . /cloudianInstall.sh force
    The “force” switch is required since we’re not using the recommended minimum resuorces, use “./cloudianInstall.sh dnsmasq force” if you need a DNS.
  • 1) Install Cloudian HyperStore
    • Please enter survey file name: /opt/cloudian-staging/7.2.1/survey.csv
    • Would you like to use key ./cloudian-installation-key? Yes
    • Please enter your top level domain name: vcsp.local
    • Please enter the service metadata replication strategy for nordics: Accept default
    • Please enter your NTP time server(s): Accept default or enter to you preferred NTP Server
    • Region [Nordics] S3 service domain URLs: Accept default
    • Region [Nordics] S3 Web site end point: Accept default
    • Admin endpoint: Accept default
    • IAM endpoint: Accept default
    • Domain name for you Cloudian Management Console service: Accept default
    • Installation will kickoff and take a couple of minutes to complete
  • 4) Advanced Configuration Options
    • e) Configure SSL for S3
      • a) Generate keystore for S3
        • Are these settings ok? Yes
      • b) Enable/Disable HTTPS for S3
        • Do you wish to enable HTTPS access on S3 server? Yes
      • x) Return to previous menu
    • x) Return to Main Menu
  • 2) Cluster Management
    • b) Push Configuration Settings to Cluster
      • Enter a comma-separated list of hosts in nordics to execute agents on? [Empty for all]: Press enter
    • c) Manage Services
      • 5) S3 service
        • Type restart and press enter
      • X) Quit
    • D) Run validation tests
    • x) Return to Main Menu
  • x) Exit
  • Close the session
  • Open a browser: https://cmc.vcsp.local:8443/
    • Login using admin / public
    • Click the top link displayed: No Storage Policies have been defined. Please create a Storage Policy to create a storage policy
  • Click + Create Storage Policy in the top right corner
    • Give it a Policy Name and accept all other default settings
    • Click Save
  • Click Users & Groups in the top bar
    • Click Manage Groups in in the top
    • Click + New Group
    • Give it a Group Name: Backupusers
    • Click Save
  • Click Manage Users in the top bar
  • Click + New user in the top right corner
    • Give it a User ID: veeam_backup_user
    • Add a password (min 9 chars)
    • Assign the Group Name created in earlier step: Backupusers
  • In the field “Search For A User By ID:” type veeam_backup_user and click search
    • Click Security Credentials for the user veeam_backup_user
    • Copy Access Key ID and then click View Secret Key to access and copy it for use later
  • Click Close
  • Sign out of the CMC GUI

Enable object lock on Cloudian

  • For more detail on Object lock you should read the document Cloudian-QuickStartGuide-Object-Lock.pdf, below is a summary of the steps outlined in that document that needs to be taken
    • Log into the Puppet Master node (should be cloudian01) as the root user.
    • Check to confirm that the HSH is currently disabled.
      • [root@cloudian01]# hsctl config get hsh.enabled
        False
    • Set hsh.enabled to true.
      • [root@cloudian01]# hsctl config set hsh.enabled=true
    • Push the configuration change out to the cluster.
      • [root@cloudian01]# hsctl config apply hsh
    • Confirm that HSH is now enabled.
      • [root@cloudian01]# hsctl config get hsh.enabled
        True
  • HSH is now enabled in your system, but no users are yet able to log into it. To provision the default admin user for HSH do the following steps:
    • log into the CMC as the admin user with password public
    • Change the “admin” user’s password. in the top right corner, Admin->Security Credentials. This password change causes the system to create a corresponding HSH user.
  • Once an HSH user has been created, that user can use SSH to log into any HyperStore node. Prefix sa_ should be applied to the admin account when logging on, so user should be sa_admin and password should be <new root password>. The prompt will appear as follows:
    sa_admin@cloudian01$
    • You can confirm that you are in the HyperStore shell by typing help:
      sa_admin@cloudian01$ help
    • Type exit and press enter to end session
  • Log on to cloudian01 via console or ssh using root with <new root password>
  • To disable root password access to all HyperStore nodes:
    • cd /opt/cloudian-staging/7.2.1
    • ./cloudianInstall.sh
    • 4) Advanced Configuration Options
      • m) Disable the root password
        • Do you wish to disable the root password on all Cluster nodes? Yes
      • X) Return to Main Menu
    • X) Exit
    • Type exit and press enter
    • Try to logon again using console or ssh and verify the root is no longer able to logon.
  • To create a bucket with object lock this must be done using an API or using AWS command line interface, it can’t be done from the Cloudian CMC.
    On a management PC, download AWS S3 CLI to create a bucket with object lock.
    • Start a command line interface (cmd) and type:
      aws configure
      (access key and secret key from veeam_backup_user will be requested)
    • Next type:
      aws s3api --endpoint-url https://s3-nordics.vcsp.local --no-verify-ssl create-bucket --object-lock-enabled-for-bucket --bucket veeam_backup_bucket0001
    • Verify bucket creation and settings:
      aws s3api --endpoint-url https://s3-nordics.vcsp.local --no-verify-ssl get-object-lock-configuration --bucket veeam_backup_bucket0001

Create Veeam components

  • Logon to Veeam Backup & Replication server
    • Start the Veeam Backup & replication GUI
      • Go to the Backup Infrastructure tab (bottom left)
        • Click Backup Repositories (top left)
        • Click Add Repository
          • Click Object Storage
          • Click S3 Compatible
          • Give it a name: Cloudian-nordics-with-object-lock and click Next
          • Enter Service Point: s3-nordics.vcsp.local
          • In the Credentials field, click Add
          • Add Access key and Secret Key copied from earlier steps for user veeam_backup_user
          • Click OK
          • Click Next
          • Click Continue for the Certificate Security Alert
          • In the Folder field, Click Browse… and create a folder for the backups
          • Click New folder and specify a name
          • Click OK
          • Set any restrictions to use:
            Limit object storage consumption to:
            Make recent backups immutable for:
  • Click Next
  • Click Finish
  • Create a new repository to be used as the performance tier of a new Scale-Out Backup repository
  • Create a new Scale-Out Backup Repository
    • The steps involved can be found on the Veeam HelpCenter pages
      • Select performance tier just created
      • Select capacity tier: Cloudian-nordics-with-object-lock
        • Make sure to click “Copy backups to object storage as soon as the are created!
  • Create a backup job and use Scale-Out backup repository above as target, and start it.

    Verify Object lock
    • Once backup job is finished
      • Go to Home
        • Under Backups find Object storage
        • Right click the backup job and select delete from disk
        • If everything is configured correctly you should get a failed attempt!

By using Veeam Backup & Replication version 10 in combination with a Scale-Out backup repository including an object based storage solution, we can make sure that our valuable data is protected, we get 2 backup copies automatically when using copy-mode, we get a second media type and we get a write protected copy with the immutability option. So in a single job we can actually adhere to the design princple we’ve talked about for a long time called the 3-2-1-rule. How cool is that!

So what we’ve now established is a solid solution that will protect your data no matter if it’s from malicious insiders or ransomware!

In the next blog post will be a follw up on this post where I’ll show you how easy it it’s to recover from a disaster including the Veeam Backup & Replication server, a total site failure. I’ll show you that as long as you have a copy of you backup available in object storag solution (not part of the site that filed of course), you can recover!

Replica seeding to vCloud Director

One of the many use cases for Veeam Backup & Replication is disaster recovery, as the name of the product suggests it can certainly replicate virtual machines from a production environment to a secondary- or disaster recovery environment. While it is a very straight forward process running through a wizard selecting source and target environments and the start replicating the VM cross the network, you can even have your virtual machines replicated to a Veeam Cloud & Service Provider, VCSP, if you don’t have a disaster recovery site of your own. The VCSP can have a hypervisor environment built for either Microsoft Hyper-V, VMware vSphere or VMware vCloud Director. VMware vCloud Director is VMware’s multi-tenant solution to host Infrastructure as a Service and purpose built specifically for Service Providers.

In this post I’m describing the process of replicating VMs to a VCSP using a feature of Veeam Backup & Replication called Cloud Connect, I’m not going through how to setup Cloud Connect. If you need more information about the ins and outs of Cloud Connect please visit Luca Dell’Oca’s webpage about Cloud Connect.

In the hosted environment at the VCSP you can power on virtual machines if needed to keep your business going if there’s a catastrophic event at your own site for instance a lengthy power outage, load shedding, you can even create a fail-over plan dictating which virtual machines should be powered on and in which order they should start, making sure everything starts in the correct order.

Replicating over the network may not be optimal in all scenarios, at least not the first initial full replication cycle. Let’s say you have a few very large virtual machines that you want to protect by sending them to a disaster recovery site hosted by your Veeam Cloud Service Provider but it’s too big to actually be transferred over the network within the available backup window, what do you do?

In Veeam Backup & Replication you can seed an initial copy of the virtual machine to your service provider using some sort of transportable solution. USB drives, Tapes or solutions of that nature – using “sneaker net”. The basic concept is to get a copy of the virtual machine to the service provider so they can import the VM to their environment and when you start replicating over the network you just send the changes made to the VM that has occurred since you made the copy of the VM. No need for a full transfer of the VM cross the network!

So the 3 basic steps that needs to be taken:

  • Backup VM to a transportable storage device and send it to VCSP
  • The VCSP imports the VM to the correct Org vDC in vCloud Director
  • Set up a replication job at the customer site using the imported VM at the VSCP site as mapping VM

If the service provider has a multi-tenant virtualization layer, meaning built on VMware vCloud Director, the process is simple but has to been broken down into a few distinct steps. If you as a service provider are using VMware vCloud Director 9.7, these are the steps you take if the customer has Veem Backup & Replication installed that can be used:

Step 1 – Customer environment
Backup source VM (normal backup job or VeeamZip) to a portable storage solution. Either backup to C:\Backup and move the backupfile manually to the USB device or select “VeeamZIP…” and specify the target USB devices directly.
VeeamZIP

Step 2 – Customer environment

Step 3 – Customer environment

Step 4 – Customer environment
When the backup is completed it should be visible in the “Backups”-section in “Disk (VeeamZIP)”

Step 5 – Customer environment
Transfer the backupfile using a transportable storage solution (a USB drive can be used)

Step 6 – VCSP environment
Connect USB drive and import backup file to Veeam Backup & Replication running at the VCSP data center. Click “Import Backup” in the top section.

Step 7 – VCSP environment
Select the backupfile on the USB device and click “Open” (you may need to change the file type selector to “Backup files (*.vbk)” to see the backupfile.

Step 8 – VCSP environment
Now Veeam Backup & Replication will import the backup

Step 9 – VCSP environment
Right click the VM from the imported backup and select “Restore entire VM…”

Step 10 – VCSP environment

Step 11 – VCSP environment
Select “Restore to a new location, or with different settings”

Step 12 – VCSP environment
Click “Host…”

Step 13 – VCSP environment
Select a host or a cluster that is under vCloud Director management where the customer has a virtual datacenter (shows up as a resource source pool in the next few steps)

Step 14 – VCSP environment
Select the VM and click “Pool…”

Step 15 – VCSP environment
Select resource pool (Org vDC of the customer)

Step 16 – VCSP environment

Step 17 – VCSP environment

Step 18 – VCSP environment
Map network adapter to desired network in the Org vDC

Step 19 – VCSP environment

Step 20 – VCSP environment

Step 21 – VCSP environment

Step 22 – VCSP environment
Log on to vCloud Director using the flex UI (the HTML5 UI lacks the “import from vSphere” option.

If you as a service provider are using VMware vCloud Director 10 with the new HTML5 UI for providers, please note that “import from vSphere” is not available in the H5 UI. What’s even more annoying is that the flex UI has also been disable by default in vCD 10 so to be able to import the VM into the Org vDC of the customer you first need to enable the flex UI of vCD:

Enable the vCloud Director Web Console

Step 23 – VCSP environment
Import VM in vCD from vSphere

Step 24 – VCSP environment
Select “Move VM” and not “Copy VM” in Import wizard

Step 25 – VCSP environment

Step 26 – VCSP environment

Step 27 – Customer environment
Set up a new replication job at customer side

Step 28 – Customer environment
Select “Replica seeding (for low bandwidth DR sites)”

Step 29 – Customer environment
Select the source VM from the customer production hypervisor (the same used in step 1)

Step 30 – Customer environment
In the “Destination”-tab, for the “Host or cluster:”-selection. Choose “Cloud host…”

Step 31 – Customer environment
Select the Org vDC to use (same as in step 15)

Step 32 – Customer environment
Select vApp and Storage policy to be used

Step 33 – Customer environment
Select desired restore points to keep

Step 34 – Customer environment
Select desired replication mode

Step 35 – Customer environment
In the “Seeding”-tab. In the “Replica mapping” section. Select “Map replicas to exsiting VMs”, click on the VM and select edit.

Step 36 – Customer environment
Select the seeded VM from step 17

Step 37 – Customer environment

Step 38 – Customer environment
Set a desired replication schedule

Step 39 – Customer environment
If desired: Click “Run the job when I click Finish”
Click “Finish”

Step 40 – Customer environment
Verify that replication successfully finish

Step 41 – Customer environment
The replication job only transfers changed blocks since the backup/import was made

Bulk deploy Veeam Linux Proxies

In version 10 of Veeam Backup & Replication a lot of Linux love has been put in to the product. To me, one of the most interesting things is the new functionality where you can assign a Linux VM the role of a backup proxy. Historically the proxy functionality has been restricted to Windows OS only. The linux proxy does not come as a prebuilt Veeam appliance, just as with Windows proxies you still need to secure and patch the operating system. The rational behind it is easy to understand, most organizations already have some sort of patch management system in place to leverage for their production workload and you would want to have the same level of patching and security on your proxies as you have for all other workloads. I thought it would interesting to see if you could automate the deployment of proxy servers a bit. Sure enough it is a fairly simple process since Veeam Backup & Replication has a great PowerShell extension which will let you automate almost all of the tasks you can do in the GUI. As far as automating proxy servers go, my colleague Anthony Spiteri has a comprehensive project called “Project Ōtosukēru” based on Terraform which may be of interest to you as well.

As a side note, Veeam Backup & Replication version 10 contains a wide variety of new features and updates, the Veeam Vanguards made a list of their top features.

Mind you, the code below should serve as an indication of what you can do – as an example if you will. However, you use at at your own risk. I’ve put in an option to deploy to a test/lab environment (if you are lucky enough to have a lab environment) so you can start testing it out in a safe environment.

So why not combine this small project with the small Linux operating system VMware provides called PhotonOS? PhotonOS is a stripped down linux operating system we can use. Now you can certainly download an iso image and do a traditional install and set it up just the way you’d like and then convert it to a template in vSphere and make use of it that way. However I thought it would be more interesting to see how much you can automate. So instead I’m just downloading the prebuilt Linux appliance and using that as the source for my proxies.

The script performs 4 different tasks:

  • It starts by importing the settings you specified in the configuration file (config.json)
  • Download required components if they’re not available. Two components are needed: The PhotonOS OVA and a powershell script by William Lam called VMKeystrokes.ps1. VMKeystrokes is needed to change the initial password of the appliance.
  • Let’s you choose where to deploy the Linux appliance, you can pick a single host, all hosts in a specific cluster or all hosts in a specific datacenter. It will also let you choose if you’d like to deploy to a test/lab environment or to a production environment (settings fetched from config.json). The script will try to ping the IP range configured in config.json to verify that they are not being used. It then deploys the appliance to the selected target(s). Once deployed the appliance will be configured (Connecting to the specified network portgroup in vSphere, Set vCPU and vRAM, set Static IP address, firewall ports opened, configuring timezone).
  • The Linux server will then be added to Veeam Backup & Replication as a managed server. The managed server will then have the role Backup Proxy assigned to it, concurrent tasks will be set to whatever amount of vCPU’s you’ve assigned to the VM (from the configuration file).

Config.json explained
“location”: – Where files be downloaded and working directory
“ovasource”: – URL to the OVA
“ovaname”: – Name of the OVA
“ProxyBaseName”: – Base name of Proxy VM to be deployed
“ProxyvCPU”: – vCPUs to assign the Proxy VM
“ProxyvRAM”: – vRAM to assign the Proxy VM
“sshuser”: “root” – Logon account for the Proxy VM
“ovainitialpassword”: – Default password of the OVA is “changeme”
“newsshpassword”: – New password to apply for the root user on the Proxy VM

“Prod”: {
“vbrserver”: – IP adress to Veeam Backup & Replication server
“vcserver”: – IP adress to VMware vCenter Server
“network”: – Portgroup the Proxy VM will be connected to
“startipaddress”: – Start of IP pool the Proxy VMs will use
“endipaddress”: – End of IP pool the Proxy VMs till use
“vbruser”: – User to connect to Veeam Backup & Replication
“vcuser”: – User to connect to VMware vCenter Server
“vcdatacenter”: – Datacenter in vCenter to use
“gateway”: – IP address of gateway for the Proxy VM
“dns”: – IP address of DNS for the Proxy VM
“domains”: – DNS Search Domains for the Proxy VM
“ntpserver”: – NTP Server for the Proxy VM to use

The Proxy VM will be named with ProxyBaseName + IP address of the target host to where the VM is deployed with all dots replaced by dashes, i.e “VeeamProxy_10-10-50-38”.

Save the two files to c:\temp and then you’re good to go!
No more bits needed to be downloaded, the script will download what it’s required. The only thing you need to change is the settings in config.json to reflect your environment.

Download Deploy_Veeam_Linux_Proxy.ps1
Download config.json

The script will add proxies based on IP addresses to Veeam Backup & Replication in this version, but per Veeam recommendation FQDNs should be used.

Deploy_Veeam_Linux_Proxy.ps1

  1. # Deploy_Veeam_Linux_Proxy.ps1
  2. # Version: 1.0
  3. # Author: Niclas Borgstrom, Veeam Cloud Solution Architect EMEA
  4. #
  5. # Synopsis: 
  6. # This script will download a linux appliance (based on VMware PhotonOS)
  7. # and deploy the appliance to a host, cluster or datacenter of your choice.
  8. # It will also download VMKeystrokes.ps1 by William Lam, VMware in order to 
  9. # do the initial configuration of PhotonOS.
  10. # When the OVA is deployed it will be configured with a static IP address,
  11. # firewall will be opened for Veeam Backup Proxy specific ports, vCPU and
  12. # vRAM will be changed and the VM will be added to Veeam Backup &amp; Replication
  13. # as a managed server and then be assigned the proxy role. Concurrent tasks
  14. # will be set according to the vCPUs assigned to the VM.
  15. #
  16. # You can choose to deploy either to a production- or a test environment, if 
  17. # available. The OVA will only be deployed to powered on hosts.
  18. #
  19. # Disclaimer:
  20. # The script is for demonstration purpose only, run it at your own risk
  21. #
  22. # Credits
  23. # 'My-Logger' function by William Lam, VMware
  24. #
  25. # Prereqs:
  26. # - VMware environment managed by vCenter
  27. # - Veeam Backup &amp; Replication already installed on a server.
  28. # - Internet access to download PhotonOS and VMKeystrokes.ps1 to change the default 
  29. #    password on the PhotonOS appliance.
  30. #
  31. # Limitations:
  32. # - Linux proxy can't be used as a 'Guest Interaction Proxy'
  33. # - Linux proxy can't be used as a 'File Backup Proxy'
  34. # - Linux Proxy only supports Hot-Add/Virtual appliance mode
  35. #
  36. # Changelog:
  37. # v 1.0: Initial release
  38.  
  39. $global:BaseDirectory = "C:\temp\"
  40. $global:BaseConfig = "config.json"
  41. $verboseLogFile = $global:BaseDirectory + "Veeam_Linux_Proxy_Deployment_" + $(Get-Date -Format "yyyy-MM-dd_HH-mm") + ".log"
  42.  
  43. Function My-Logger {
  44.     param(
  45.     [Parameter(Mandatory=$true)]
  46.     [String]$message
  47.     )
  48.  
  49.     $timeStamp = Get-Date -Format "yyyy-MM-dd_HH:mm:ss"
  50.  
  51.     Write-Host -NoNewline -ForegroundColor White "[$timestamp]"
  52.     Write-Host -ForegroundColor Green " $message"
  53.     $logMessage = "[$timeStamp] $message"
  54.     $logMessage | Out-File -Append -LiteralPath $verboseLogFile
  55. }
  56.  
  57. # Load and parse the JSON configuration file 
  58. My-Logger "Loading JSON configuration file $BaseDirectory$BaseConfig"
  59. try { 
  60. 	$global:Config = Get-Content "$BaseDirectory$BaseConfig" -RAW -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | ConvertFrom-Json -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
  61.  
  62. } catch { 
  63. 	My-Logger "[ERROR] The configuration files is missing!"
  64. 	Break
  65. } 
  66.  
  67. # Check the configuration
  68. if (!($Config)) {
  69.     My-Logger "[ERROR] The configuration file is missing!"
  70.     Break
  71. }
  72.  
  73. $location = $Config.General.location
  74. $ovasource = $Config.General.ovasource
  75. $ovaname = $Config.General.ovaname
  76. $proxybasename = $Config.General.ProxyBaseName
  77. $proxyvcpu = $Config.General.ProxyvCPU
  78. $proxyvram = $Config.General.ProxyvRAM
  79. $sshuser = $Config.General.sshuser
  80. $ovainitialpassword = $Config.General.ovainitialpassword
  81. $newsshpassword = $Config.General.newsshpassword
  82.  
  83. # Set temp location
  84. Set-Location $location
  85.  
  86. try {
  87. 	Add-PSSnapin -Name VeeamPSSnapin -ErrorAction Stop
  88. 	Import-Module -Name VMware.VimAutomation.Core -ErrorAction Stop
  89. } catch {
  90. 	My-Logger "[ERROR] PowerCLI or VeeamPSSnapin not installed."
  91. 	Break
  92. }
  93.  
  94. # Verify that VMKeystrokes.ps1 is available
  95. My-Logger "Checking VMkeystrokes.ps1..."
  96. Clear-Host
  97. try { 
  98. 	# Dot source VMKeystrokes.ps1 if it's available
  99. 	. .\VMKeystrokes.ps1
  100.  
  101. } catch {
  102. 	# If VMKeystrokes.ps1 isn't available, ask if it should be downloaded
  103. 	My-Logger "  [WARNING] Unable to find 'VMKeystrokes.ps1' in $location"
  104. 	$downloadvmkeystrokes = if(($downloadvmkeystrokes = Read-Host "`nWould you like to download it (Y/N) or press enter to accept default value [Y]") -eq '') {"Y"} else {$downloadvmkeystrokes}
  105. 	if ($downloadvmkeystrokes.ToLower() -eq "y") {
  106. 		My-Logger "  Downloading 'VMKeystrokes.ps1'"
  107. 		Invoke-WebRequest -Uri "https://raw.githubusercontent.com/lamw/vghetto-scripts/master/powershell/VMKeystrokes.ps1" -OutFile ".\VMKeystrokes.ps1"
  108. 		. .\VMKeystrokes.ps1
  109. 	} else {
  110. 		My-Logger "  [ERROR] Can't continue without VMkeystrokes.ps1, exiting..."
  111. 		Break
  112. 	}
  113. }
  114.  
  115. $targethosts = $null
  116.  
  117. # Verify that PhotonOS it available
  118. My-Logger "Checking PhotonOS OVA..."
  119. Clear-Host
  120. if(!(Test-Path ($location + "\" + $ovaname))) {
  121. 	My-Logger "  [WARNING] Unable to find PhotonOS OVA: $($location + "\" + $ovaname)"
  122. 	$downloadova = if(($downloadova = Read-Host "`nWould you like to download it (Y/N) or press enter to accept default value [Y]") -eq '') {"Y"} else {$downloadova}
  123. 	if ($downloadova.ToLower() -eq "y") {
  124. 		My-logger "  Downloading $($location + "\" + $ovaname)"	
  125. 		Invoke-WebRequest -Uri $ovasource -OutFile $($BaseDirectory + "\" + $ovaname)
  126. 	} else {
  127. 		My-Logger "  [ERROR] PhotonOS OVA not available!"
  128. 		Break
  129. 	}
  130. }
  131.  
  132. # Select where to deploy Linux Proxies
  133. Clear-Host
  134. Write-Output "`nWould you like to deploy to prod or test:`n"
  135. Write-Output "1. Production environment - $($Config.Prod.vcserver)"
  136. Write-Output "2. Test environment - $($Config.Test.vcserver)"
  137. $selectenvironment = if(($selectenvironment = Read-Host "`nSelect item or press enter to accept default value [1]") -eq '') {"1"} else {$selectenvironment}
  138.  
  139. # Populate strings based on selected deployment type
  140. if ($selectenvironment -eq "1") {
  141. 	My-Logger "Deploying to Production environment $($Config.Prod.vcserver)"
  142. 	$vbrserver = $Config.Prod.vbrserver
  143. 	$vcserver = $Config.Prod.vcserver
  144. 	$network = $Config.Prod.network
  145. 	$startipaddress = $Config.Prod.startipaddress
  146. 	$endipaddress = $Config.Prod.endipaddress
  147. 	$vbruser = $Config.Prod.vbruser
  148. 	$vcuser = $Config.Prod.vcuser
  149. 	$vcdatacenter = $Config.Prod.vcdatacenter
  150. 	$gateway = $Config.Prod.gateway
  151. 	$dns = $Config.Prod.dns
  152. 	$domains = $Config.Prod.domains
  153. 	$ntpserver = $Config.Prod.ntpserver
  154. } elseif ($selectenvironment -eq "2"){
  155. 	My-Logger "Deploying to Test environment $($Config.Test.vcserver)"
  156. 	$vbrserver = $Config.Test.vbrserver
  157. 	$vcserver = $Config.Test.vcserver
  158. 	$network = $Config.Test.network
  159. 	$startipaddress = $Config.Test.startipaddress
  160. 	$endipaddress = $Config.Test.endipaddress
  161. 	$vbruser = $Config.Test.vbruser
  162. 	$vcuser = $Config.Test.vcuser
  163. 	$vcdatacenter = $Config.Test.vcdatacenter
  164. 	$gateway = $Config.Test.gateway
  165. 	$dns = $Config.Test.dns
  166. 	$domains = $Config.Test.domains
  167. 	$ntpserver = $Config.Test.ntpserver
  168. } else {
  169. 	My-Logger "[ERROR] Wrong selection..."
  170. }
  171.  
  172. # Function to build a dynamic menu for infrastructure components (Datacenter, Cluster or Host)
  173. Function Get-HostList {
  174.     Param (
  175.         [Parameter(Mandatory)]
  176.         [ValidateNotNullOrEmpty()]
  177.         $ListItem,
  178.  
  179.         [Parameter(Mandatory)]
  180.         [ValidateNotNullOrEmpty()]
  181.         $GetItem
  182.     )
  183.  
  184.     try {
  185.         $menu = @{}
  186.         For ($i=1;$i -le $ListItem.count; $i++) { 
  187.             Write-Host "$i. $($ListItem[$i-1].Name)"
  188.             $menu.Add($i,($ListItem[$i-1].Name)) 
  189.         }
  190.         [int]$ans = if (($ans = Read-Host "`nSelect item or press enter to accept default value [1]") -eq '') {"1"} else {$ans}
  191.         $Selection = $menu.Item($ans); Invoke-Expression $($GetItem)
  192.     } catch {
  193.         Write-Host "The selection you made is unavailable, please make a valid selection between 1 and $($i-1)..."
  194.     }
  195. }
  196.  
  197. # Connect to VMware vCenter Server and Veeam Backup &amp; Replication
  198. #Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
  199. My-Logger "Connecting to VMware vCenter Server $vcserver"
  200. $vicredential = Get-Credential -UserName $vcuser -Message "Enter password for VMware vCenter server: $vcserver"
  201. Connect-VIServer $vcserver -Credential $vicredential -WarningAction SilentlyContinue
  202.  
  203. My-Logger "Connecting to Veeam Backup &amp; Replication Server $vbrserver"
  204. $vbrcredential = Get-Credential -UserName $vbruser -Message "Enter password for Veeam Backup &amp; Replication server: $vbrserver"
  205. Connect-VBRServer -Server $vbrserver -Credential $vbrcredential -WarningAction SilentlyContinue
  206.  
  207. # Select if scope of deployment
  208. Clear-Host
  209. Write-Output "`nWould you like to deploy a proxy to:`n"
  210. Write-Output "1. A Single Host"
  211. Write-Output "2. A Cluster (to all hosts in a specific cluster)"
  212. Write-Output "3. A Datacenter (to all hosts in a specific datacenter)"
  213. [int]$option = if(($option = Read-Host "`nSelect item or press enter to accept default value [2]") -eq '') {"2"} else {$option}
  214.  
  215. if ($option -eq "1") {
  216. 	$MyQuery = (Get-Datacenter $vcdatacenter | Get-VMHost)
  217. 	$MyList = "Get-VMHost `$Selection | Where-Object -FilterScript { `$_.PowerState -eq 'PoweredOn' }"
  218. 	My-Logger "Deploying to Host"
  219. } elseif ($option -eq "2"){
  220. 	$MyQuery = (Get-Datacenter $vcdatacenter | Get-Cluster)
  221. 	$MyList = "Get-Cluster `$Selection | Get-VMHost | Where-Object -FilterScript { `$_.PowerState -eq 'PoweredOn' }"
  222. 	My-Logger "Deploying to Cluster"
  223. } elseif ($option -eq "3"){
  224. 	$MyQuery = (Get-Datacenter)
  225. 	$MyList = "Get-Datacenter `$Selection | Get-Cluster | Get-VMHost | Where-Object -FilterScript { `$_.PowerState -eq 'PoweredOn' }"
  226. 	My-Logger "Deploying to Datacenter"
  227. } else {
  228. 	My-Logger "Wrong selection..."
  229. }
  230.  
  231. Clear-Host
  232. Write-Output "Select where to deploy Linux Proxies:`n"	
  233. $targethosts = (Get-HostList -ListItem $MyQuery -GetItem $MyList)
  234.  
  235. # Verify the selected object actually contains powered on hosts
  236. if ($null -eq $targethosts) {
  237. 	My-Logger "No powered on hosts found..."
  238. 	Disconnect-VBRServer
  239. 	Disconnect-VIServer $vcserver -Confirm:$false
  240. 	Break
  241. }
  242.  
  243. # Check and verify assigned IP range from config.json and verify correct IP format
  244. $deployedproxies = [ordered]@{}
  245. $iplistunverified = @()
  246. $iplistverified = @()
  247. try {
  248.     [IPADDRESS]$startip = $startipaddress
  249.     [IPADDRESS]$endip = $endipaddress
  250.     $iplistunverified += $($startip.GetAddressBytes()[3])..$($endip.GetAddressBytes()[3]) | ForEach-Object {$($startip.GetAddressBytes()[0],$startip.GetAddressBytes()[1],$startip.GetAddressBytes()[2], $_ -join '.')}
  251.  
  252.     # Verify if IP addresses are available
  253.     My-Logger "Available IP addresses in range $startip to $endip :"
  254.     Clear-Host
  255.     Write-Output "Checking available IP addresses..."
  256.     foreach ($checkedip in $iplistunverified) {
  257.         if (!($(Test-Connection -BufferSize 2 -TTL 5 -ComputerName $checkedip -quiet -count 1))) {
  258.             $iplistverified += $checkedip
  259.             My-Logger "  $checkedip - available"
  260.         } else {
  261.             My-Logger "  $checkedip - in use"
  262.         }
  263.     }
  264.  
  265.     if ($iplistverified.Count -lt $targethosts.count) {
  266.         My-Logger "[ERROR] Not enough IP addresses assigned, $($targethosts.count) IP addresses are needed. Please update config.json"
  267.         Disconnect-VBRServer
  268.         Disconnect-VIServer $vcserver -Confirm:$false
  269.         Break
  270.     }
  271. } catch {
  272. 	#Clear-Host
  273. 	My-Logger "[ERROR] IP address assignment is incorrect, verify in config.json"
  274. 	Disconnect-VBRServer
  275. 	Disconnect-VIServer $vcserver -Confirm:$false
  276. 	Break
  277. }
  278.  
  279. # Deploy PhotonOS, change root password and assign IP settings, add VM as Managed Server and assign Proxy Role
  280. $ipincrement = 0
  281. foreach ($targethost in $targethosts) {
  282. 	My-Logger "Processing host: $targethost"
  283. 	$sw = [Diagnostics.Stopwatch]::StartNew()
  284.  
  285. 	# Verify if a proxy is already present on host or deploy proxy if it's missing
  286. 	if (Get-VMHost $targethost | Get-VM | Where-Object { $_.Name -like $($ProxyBaseName + "_*") }) {
  287. 		My-Logger "  A Veeam Proxy is already deployed to host: $targethost"
  288. 	} else {	
  289. 		$ProxyName = $ProxyBaseName + "_" + ($targethost.name).replace(".","-")
  290. 		My-Logger "  Importing PhotonOS OVA $ProxyName"
  291. 		$vm = Import-VApp -Source $ovaname -Name $ProxyName -VMHost $targethost -DiskStorageFormat thin
  292. 		# "VM Netork" will be used to attach NIC, must be present on host
  293. 		My-Logger "  Assigning resources to $ProxyName"
  294. 		$vm | Set-VM -NumCpu $proxyvcpu -MemoryGB $proxyvram -Confirm:$false
  295. 		$vm | Get-NetworkAdapter -Name "Network adapter 1" | Set-NetworkAdapter -Portgroup $network -Confirm:$false
  296. 		$vm | New-AdvancedSetting -Name disk.enableUUID -Value TRUE -Confirm:$false -Force:$true
  297.  
  298. 		Start-VM $vm
  299.  
  300. 		Wait-Tools -VM $vm
  301. 		Start-Sleep 10
  302. 		My-Logger "  VMKeystrokes: Sending user account to $vm"
  303. 		Set-VMKeystrokes -VMName $VM -StringInput $sshuser -ReturnCarriage $true
  304. 		Start-Sleep 2
  305. 		My-Logger "  VMKeystrokes: Sending inital OVA password to $vm"
  306. 		Set-VMKeystrokes -VMName $VM -StringInput $ovainitialpassword -ReturnCarriage $true
  307. 		Start-Sleep 2
  308. 		My-Logger "  VMKeystrokes: Sending initial OVA password to $vm"
  309. 		Set-VMKeystrokes -VMName $VM -StringInput $ovainitialpassword -ReturnCarriage $true
  310. 		Start-Sleep 2
  311. 		My-Logger "  VMKeystrokes: Sending new password to $vm"
  312. 		Set-VMKeystrokes -VMName $VM -StringInput $newsshpassword -ReturnCarriage $true
  313. 		Start-Sleep 2
  314. 		My-Logger "  VMKeystrokes: Sending new password to $vm"
  315. 		Set-VMKeystrokes -VMName $VM -StringInput $newsshpassword -ReturnCarriage $true
  316.  
  317. 		# Install and update PhotonOS
  318. 		# https://github.com/Vanarga/vmware/wiki/2a.-Configuring-Photon-OS
  319. 		# insert 'yum update -y' last in the $cmd section if an automatic update should be performed
  320. 		Start-Sleep 10
  321. 		$ipofvm = $iplistverified[$ipincrement]
  322. 		My-Logger "  Configuring $ProxyName with IP: $ipofvm"
  323.  
  324. 		$cmd = @"
  325. 		yum install nano perl mlocate -y
  326. 		hostnamectl set-hostname $ProxyName
  327. 		iptables -A INPUT -p tcp --match multiport --dports 2500:3300 -j ACCEPT
  328. 		iptables -A OUTPUT -p icmp -j ACCEPT
  329. 		iptables -A INPUT  -p icmp  -j ACCEPT
  330. 		iptables-save &gt;/etc/systemd/scripts/ip4save
  331. 		timedatectl set-timezone Europe/Stockholm
  332. 		echo "[Match]" &gt; /etc/systemd/network/10-static-en.network
  333. 		echo "Name=eth0" &gt;&gt; /etc/systemd/network/10-static-en.network
  334. 		echo " " &gt;&gt; /etc/systemd/network/10-static-en.network
  335. 		echo "[Network]" &gt;&gt; /etc/systemd/network/10-static-en.network
  336. 		echo "Address=$ipofvm/24" &gt;&gt; /etc/systemd/network/10-static-en.network
  337. 		echo "Gateway=$gateway" &gt;&gt; /etc/systemd/network/10-static-en.network
  338. 		echo "DNS=$dns" &gt;&gt; /etc/systemd/network/10-static-en.network
  339. 		echo "Domains=$domains" &gt;&gt; /etc/systemd/network/10-static-en.network
  340. 		echo "NTP=$ntpserver" &gt;&gt; /etc/systemd/network/10-static-en.network
  341. 		echo "LinkLocalAddressing=no" &gt;&gt; /etc/systemd/network/10-static-en.network
  342. 		echo "IPv6AcceptRA=no" &gt;&gt; /etc/systemd/network/10-static-en.network
  343. 		chmod 644 /etc/systemd/network/10-static-en.network
  344. 		systemctl restart systemd-networkd.service
  345. 		systemctl daemon-reload
  346. "@
  347.  
  348. 		My-Logger "  Invoking script on $ProxyName"
  349. 		Invoke-VMScript -VM $VM -ScriptText $cmd -GuestUser $sshuser -GuestPassword $newsshpassword -ScriptType Bash
  350.  
  351. 		# Add Proxy VM to VBR as managed server and add proxy role
  352. 		if ((Get-PSSnapin VeeamPSSnapin).Version.Major -ge 10) {
  353. 			My-Logger "  Adding $ipofvm as a Veeam Managed Server"
  354. 			Add-VBRLinux -Name $ipofvm -SSHUser $sshuser -SSHPassword $newsshpassword -Description "Linux Server based on PhotonOS 3.0 Revision 2"
  355. 			My-Logger "  Adding Backup Proxy Role"
  356. 			Add-VBRViLinuxProxy -Server (Get-VBRServer -Name $ipofvm -Type Linux) -Description "Linux Backup Proxy based on PhotonOS 3.0 Revision 2" -MaxTasks $proxyvcpu -Force
  357. 			My-Logger "  Veeam Proxy was deployed to host: $targethost"
  358. 		} else {
  359. 			My-Logger "  [ERROR] You need at least Veeam Backup &amp; Replication version 10 to add a Linux Proxy"
  360. 			Disconnect-VBRServer
  361. 			Disconnect-VIServer $vcserver -Confirm:$false
  362. 			Break
  363. 		}
  364.  
  365.  
  366. 		# Collect information on Proxies in hashtable for future use
  367. 		$deployedproxies.add($proxyname,$ipofvm)
  368. 		$ipincrement++
  369. 		$ipofvm = $null
  370. 		My-Logger "  Deployment of proxy took: $($sw.Elapsed.Minutes) minutes and $($sw.Elapsed.Seconds) seconds"
  371. 	}	
  372. }
  373.  
  374. Clear-Host
  375. if (($deployedproxies).Count -eq 0) {
  376. 	My-Logger "[ERROR] Something went wrong, no proxies were deployed!"
  377. 	My-Logger "Check log file $verboseLogFile"
  378. 	Disconnect-VBRServer
  379. 	Disconnect-VIServer $vcserver -Confirm:$false
  380. } else {
  381. 	My-Logger "The following proxies were deployed:" 
  382. 	My-Logger $deployedproxies
  383. 	Disconnect-VBRServer
  384. 	Disconnect-VIServer $vcserver -Confirm:$false
  385. }

Config.json

  1. {
  2.   "General": {
  3.     "location": "C:\\temp",
  4.     "ovasource": "http://dl.bintray.com/vmware/photon/3.0/Rev2/ova/photon-hw13_uefi-3.0-9355405.ova",
  5.     "ovaname": "photon-hw13_uefi-3.0-9355405.ova",
  6.     "ProxyBaseName": "VeeamProxy",
  7.     "ProxyvCPU": "4",
  8.     "ProxyvRAM": "8",
  9.     "sshuser": "root",
  10.     "ovainitialpassword": "changeme",
  11.     "newsshpassword": "newsecretpassword"
  12.   },
  13.   "Test": {
  14. 	"vbrserver": "10.10.50.211",
  15. 	"vcserver": "10.10.50.214",
  16. 	"network": "VM Network",
  17. 	"startipaddress": "10.10.50.150",
  18. 	"endipaddress": "10.10.50.160",
  19. 	"vbruser": "Administrator",
  20. 	"vcuser": "administrator@vsphere.local",
  21. 	"vcdatacenter": "Datacenter",
  22. 	"gateway": "10.10.50.1",
  23. 	"dns": "10.10.0.2",
  24. 	"domains": "mydomain.local",
  25. 	"ntpserver": "se.pool.ntp.org"
  26.   },
  27.   "Prod": {
  28. 	"vbrserver": "10.10.10.30",
  29. 	"vcserver": "10.10.10.90",
  30. 	"network": "Prod",
  31. 	"startipaddress": "10.10.10.150",
  32. 	"endipaddress": "10.10.10.160",
  33. 	"vbruser": "Administrator",
  34. 	"vcuser": "administrator@vsphere.local",
  35. 	"vcdatacenter": "Datacenter",
  36. 	"gateway": "10.10.10.1",
  37. 	"dns": "10.10.0.2",
  38. 	"domains": "mydomain.local",
  39. 	"ntpserver": "se.pool.ntp.org"
  40.   }
  41. }

PowerShell function for menu creation revisited

Sometimes when creating blog posts you just get excited to publish a post as soon as it’s finished, but then you realize you can do something better. So yesterday I published a post on how to use a function in PowerShell to create an interactive dynamic menu but in hindsight it could have been more “generic” – so today I’m back with a new post on how you can create that generic function by providing the query in a separate string instead as part of the function itself. This allows you to merely change the query (the input for creating the menu) without having to change anything inside the function. Now it’s a “real” function! 🙂

I’ve added two mandatory parameters to the function, the first is the query to retrieve data and the second parameter is the task that you’d like to perform on the selected object. I’m calling the parameters -ListItem and -GetItem but the actual query is set in the $MyQuery and $MyTask string and they are then passed on to the function to perform the task. So if I’d like to get a list of VMs I just change the $MyQuery to something like “(Get-VM | Sort-Object)” and if I’d like to get a list of Datastores I set $MyQuery = “(Get-Datastore | Where {$_.Type -eq ‘VMFS’} | Sort-Object -Descending FreeSpaceGB)”. Once the list is presented and you select an object you then pass on what’s going to happen with it with the $MyTask – so if I want to retrieve a specific VM I set it to “Get-VM” but it could be anything (like Remove-VM but there’s no warning so be careful!)

Get a list of VMs
Get a list of VMFS datastores and sort them based on free space

Calling the function is then done using this syntax:
Set-Menu -ListItem $MyQuery -GetItem $MyTask

$VIServer = "vcsa.mydomain.com"
$VIUsername = "administrator@vsphere.local"
$VIPassword = "MyPassword"

Connect-VIServer $VIServer -User $VIUsername -Password $VIPassword -WarningAction SilentlyContinue

$MyQuery = (Get-Datastore | Where {$_.Type -eq 'VMFS'} |Sort-Object -Descending FreeSpaceGB)
$MyTask = "Get-Datastore"

Function Set-Menu {
    Param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        $ListItem,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        $GetItem
    )

    Try {
    $menu = @{}
    For ($i=1;$i -le $ListItem.count; $i++)
        { Write-Host "$i. $($ListItem[$i-1].Name)"
        $menu.Add($i,($ListItem[$i-1].Name)) }
    [int]$ans = if(($ans = Read-Host "Select item or press enter to accept default value [1]") -eq '') {"1"} else {$ans}
    $Selection = $menu.Item($ans); Invoke-Expression $($GetItem +  " " + $Selection)
    }

    Catch {
    Write-Host "The selection you made is unavailable, please make a valid selection between 1 and $($i-1)..."
    }
}

cls

Set-Menu -ListItem $MyQuery -GetItem $MyTask

Disconnect-VIServer $VIServer -Confirm:$false
Set-Menu waiting for user input
Set-Menu has executed the task defined in $MyTask

The way you can use the function is up to you but I use it in William Lams vghetto-vsphere-automated-lab-deployment script

Simplify your life with dynamic menus in PowerShell

If you are anything like me you’re setting up test or demo environments and then tearing them down a few hours later when you’re done with what ever testing you were doing. While setting up a VMware vSphere test environment is super easy using powershell/powercli (if you haven’t already visited William Lams web page, I highly recommend it and while you’re there grab the PowerShell scripts to deploy vSphere/vSAN/NSX environments. Kudos to William for everything you do for the vCommunity!!), I use his powershell scripts almost on a daily basis!

Now while setting up a single lab environment is usually not a big problem using the scripts provided by Willam but when you start setting up multiple labs (I typically have like 3 or 4 labs set up on any given time for different purposes) you might run out of some resources statically configured in the script, for instance your datastore configured doesn’t have enough capacity. So why not enhance the experience with dynamic selection of for instance datastore (or in my example: DatastoreCluster). Turns out it’s really easy to build an interactive dynamic menu of your datastoresclusters and use the menu to select where to install the lab environment.

I’m using a function to call the datastoreclusters I can use. I have a basic error handling included that you might need to extend. The code below includes 2 examples, the first function is calling available DatastoreClusters from a vCenter server and ordering them based on available free space and the second example gets a list of port groups available on my distributed switch. I’ve also assigned a default selection/value for faster deployments, just press enter to select the default value.

$VIServer = "vcsa.mydomain.com"
$VIUsername = "administrator@vsphere.local"
$VIPassword = "MyPassword"

Connect-VIServer $VIServer -User $VIUsername -Password $VIPassword -WarningAction SilentlyContinue

Function Show-DatastoreClusters ($Title = 'My Datastores'){
Try {
$AvailDatastores = (Get-Datastore | Where {$_.Type -eq "VMFS"} |Sort-Object -Descending FreeSpaceGB)
$menuds = @{}
For ($i=1;$i -le $AvailDatastores.count; $i++)
{ Write-Host "$i. $($AvailDatastores[$i-1].Name) - $([math]::Round($AvailDatastores[$i-1].FreespaceGB,1)) GB free space"
$menuds.Add($i,($AvailDatastores[$i-1].Name)) }
[int]$ansds = if(($ansds = Read-Host "Select Datastore or press enter to accept default value [1]") -eq ''){"1"} else {$ansds}
$DatastoreSelection = $menuds.Item($ansds) ; Get-Datastore $DatastoreSelection
}
Catch { Write-Host "The selection you made is unavailable, please make a valid selection between 1 and $($i-1)..." Start-Sleep 2 }
}

Function Show-PortGroups ($Title = 'My Portgroups'){
Try {
$AvailPortgroups = (Get-VDSwitch -Name "DSwitch" | Get-VDPortgroup)
$menupg = @{}
For ($i=1;$i -le $AvailPortgroups.count; $i++)
{ Write-Host "$i. $($AvailPortgroups[$i-1].Name)"
$menupg.Add($i,($AvailPortgroups[$i-1].Name)) }
[int]$anspg = if(($anspg = Read-Host "Select portgroup or press enter to accept default value [7]") -eq ''){"7"}else{$anspg}
$PortgroupSelection = $menupg.Item($anspg) ; Get-VDPortgroup $PortgroupSelection
}
Catch { Write-Host "The selection you made is unavailable, please make a valid selection between 1 and $($i-1)..." Start-Sleep 2 }
}
cls
Write-Host `n
$VMDatastore = Show-DatastoreClusters
Write-Host `n
$VMNetwork = Show-Portgroups
Write-Host `n
$VMDatastore
$VMNetwork

Disconnect-VIServer $VIServer -Confirm:$false

The function above can then be included in the script from William Lam. When calling the function the output will look something like this (the menus being produced are highlighted in red):

Function to build dynamic menu

If you’d like you can add some extra granularity when enumerating the datastore, expand the “Where” statement to just get the datastores with a specific name:

{$_.Type -eq "VMFS" -and $_.Name -like "VMFS-ESXi7*"}

Once you got you script fetching the desired data you can add the function to any script, I’ve added it to William’s script for some added flexibility.

How to setup Veeam replication with VMware vCloud Director

Veeam Backup & Replication 9.5 update 4 has now finally been released (to the VCSP community first and the general public on the 22:nd of January). There are loads of really interesting updates and new features.

Veeam Backup & Replication 9.5 update 4

To name a few of the enhancement/new features:

  • Capacity tier: Support for object based storage, gives you access to BLOB storage from Microsoft Azure, Amazon S3 and S3 compatible as well as IBM Cloud Object Storage. This is a new addition to Scale-Out backup repository users. You have your local “performance tier” as per usual but you can offload data based on age or space to object based storage.
  • Staged restore (GDPR compliance for instance, the right to be forgotten  or other use cases where you’d need to run a script on the VM before restoring it)
  • Secure restore where you can do a virus scan on the VM before restoring
  • Direct restore to Amazon EC2 – restoring to Azure has been available for a while but now you can also choose to restore your on-premises infrastructure VMs to Amazon EC2 – combined with the functionality of the backup vendor Veeam acquired a year ago called N2WS for backing up EC2 instances we now have a whole other level of portability of our data: backup everything, restore where it makes the most sense.
  • Self-service backup and restore portal using Enterprise manager
  • Enhancements to various Veeam explorers
  • Plugins for SAP HANA and Oracle RMAN
  • Platform support: vSphere 6.7 update 1, Windows Server 2019 and vCloud Director 9.5

But going back to the fact that update 4 now is available for VCSPs (or Veeam Cloud & Service Provider), there have been some updates for VMware environments as well (VMware calls their service provider program “VCPP”). Included in the VCPP program is a great product called vCloud Director that has been around for ages but is only available for service providers to use nowadays. VMware vCloud Director is an abstraction layer on top of vCenter so up until now there has been no support for vCloud Director for Veeam Cloud Connect usage when replicating VMs from a customer to the service provider environment. The solution previously was to replicate VMs to the service provider vCenter using Cloud Connect and then manually import VMs to the correct organization from vCloud Director. With update 4 that manual step has now been removed, and the process has in fact been improved since the customer can – using cloud connect and a single port mind you! (no VPN required) – replicate virtual machines from the onsite vSphere environment directly to their own Organization and Org vDC. The customer can also set up failover plans and run those if needed all using the same vCloud Director credentials they already received from the service provider.

It’s really easy to setup, below is a video where I show you how to configure the service provider bits such as adding vCloud Director, setting up tenants but also how the customer would configure their environment i.e. how to connect to a service provider using Cloud Connect and setting up replication jobs from a local environment and replicating VMs to the service provider vCloud Director and the customers org vDC within that environment.

(The video is in swedish but just turn off the sound if you don’t understand)

You’re missing out as a Service Provider if you’re not providing backups for Office 365

Hopefully you’ve already heard, Office 365 is a big hit for just about any vertical and customer type but have you had the much, much, needed conversation with your customers on the necessity of protecting the data that’s now landed in Office 365? I’ve said it before and I’ll say it again: Microsoft is fantastic in providing availability of the service they’re providing but however they also say that any data you store in Office 365 is yours – meaning you have the responsibility to actually think about how you’re going to protect that data and in the end also providing some sort of backup mechanism that executes the backups for you. This is described in a blog post from Veeam called the Office 365 shared responsibility model, which is an essential read if you haven’t already seen it.

A few months ago Veeam released the update version of Backup for Office 365, version 2.0,  and we’re now able to not only backup the mail part of Office 365 but also Sharepoint and Onedrive.

As a Service Provider, Veeam has a program called VCSP (Veeam Cloud & Service Provider), you have the ability to provide Backup as a Service and Disaster Recovery as a Service based on a specific Veeam Backup & Replication function called Cloud Connect available only to Service Providers. Now in relation to Office 365 you have the ability to leverage Cloud Connect to provide backup for Office 365 as a service as well for your customers. So if you are a service provider today, already using Cloud Connect – Why are you not providing backup for Officec 365 as a service? If you have Cloud Connect already installed it takes less than 10 minutes to set up the new service.

So how difficult is it to set up? Not difficult at all – in fact I’ll show you in the video below (Swedish only, but it’s not rocket science so if you’re not swedish speaking it should be fairly easy to follow along anyway). But it basically boils down to these 5 steps:

  1. Install Veeam Backup for Office 365
  2. Install a certificate
  3. Enable tenants authentication with organization credentials
  4. Configure a repository for the customer
  5. Add the customer account and set up a backup job

That’s it! In the video I will also show you how to set up a restore environment at the customer site that will let them restore items themselves using their administrative Office 365 credentials using a local installation of Backup & Replication Free edition and Veeam Explorers for Exchange and Sharepoint, but there are actually a few different ways of restoring – I’m just showing one of the options. You could also have the customers logging on to the Backup server itself for instance or provide a web portal to manage the retores. When restoring items, as always with Veeam, you have multiple destinations for your restore jobs; restore back to Office 365 (as shown in the video), restore to a .pst-file or restore an item and send it as an attachment to a mail to someone. But that’s not all, you can actually restore back to an on-premises installation of Microsoft Exchangeas well  if you’d like. In fact you can use Backup for Office 365 to do backups of your on-premises Exchange server so you have not only a backup tool but a migration tool as well – working bi-directional anyway you want!

Here’s the installation and configuration video! (Swedish only)

VMware vCloud Director not showing webpage

I was installing VMware vCloud Director 9.1 for Service Providers the other day and ran in to a problem that is “by design” if you will but if you are new to vCloud Director it still might be a show stopper for you.

In my case I was installing vCloud Director on a CentOS 7 VM.  The problem itself manifests itself when the installation is done and you try to access the webpage but all you get is an empty webpage like this:

First of all before installing vCloud Director make sure you have all the required linux packages installed on the VM:

alsa-lib    
bash
chkconfig
coreutils
findutils
glibc
grep
initscripts
krb5-libs
libgcc
libICE
libSM
libstdc++
libX11
libXau
libXdmcp
libXext
libXi
libXt
libXtst
module-init-tools
net-tools
pciutils
procps
redhat-lsb
sed
tar
wget
which

Since my environment is a demo/test environment I’m using self signed certificates but in a production environment you should use real signed certificates.

But going back to the problem, everything installed correctly during the install and I had no problem connecting to the database server (again since my environment is for demo, I’m using Microsoft SQL Server Express 2016 – not supported in a production environment).

I had no problem connecting to the vcd server (to both http and console interface) and database using either IP address or FQDN. But still a connection  problem to the webpage, smells a bit like a firewall issue?

First a look into the logs using the command

tail -f /opt/vmware/vcloud-director/logs/vmware-vcd-watchdog.log

A warning “Server status returned HTTP/1.1 503”. Verifying the active firewall rules using the command

sudo firewall-cmd –zone=public –list-services

Only the ssh and dhcpv6-client services are enabled. It seems we’re missing a few services so enabling them using:

sudo firewall-cmd –zone=public –add-service=http

sudo firewall-cmd –zone=public –add-service=https

And verifying the new firewall rules:

Looks like it just might work now, probably good thing to restart the services just to be safe:

service vmware-vcd stop

service vmware-vcd start

And after a successful restart, reopening the browser will get you the good old web page once again:

Now that looks promising, clicking “Continue to this website (not recommended) brings us to this screen below:

Now it’s time to continue configuring vCloud Director.