All three are tools fulfilling different uses or purposes. Deciding which is partially a preference and partially correct or adequate selection of a tool.
I've not used it, but from what I've read about Windows BASH, which is precious little, it is a slightly isolated BASH shell environment. It does not have access to system-level information or APIs that Powershell does, for example. It does not provide a UNIX-like command environment, nor does it provide SSH. But it can run programs and applications much like BAT files can, but with scripts written using BASH syntax.
Cygwin is a library-based abstraction of a (more-or-less) full UNIX-style POSIX environment. It can have access to system-level information and APIs if such an interface is written, and many have. It feels much more like a UNIX-style environment but there are obvious adaptations that need to be made to accomodate "windowsisms." E.g. to access a Windows drive, like D, it's
/cygdrive/d/. Directory separators in a path are
/ rather than
\ and access to a network drive is
//host/share/path... I use it daily at work and I find it very useful to my UNIX-style thinking.
Linux run in a Virtual Machine is a complete installation and (almost) completely isolated from the host system, except at specific, defined points like networking, keyboard/mouse, memory, etc...